日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java 多进程写一个文件_java高并发多线程及多进程同时写入文件研究

發(fā)布時(shí)間:2025/3/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 多进程写一个文件_java高并发多线程及多进程同时写入文件研究 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

測(cè)試&思考:

環(huán)境:windows 七、linux centos 6.三、java8html

java多線程同時(shí)寫一個(gè)文件

java高并發(fā)環(huán)境下多線程同時(shí)寫入一個(gè)文件時(shí),

經(jīng)過 FileLock 加鎖,能夠控制對(duì)文件的并發(fā)操做。同一個(gè)JVM,能夠共享部份內(nèi)存java

第一種狀況是:一個(gè)線程A有對(duì)文件加鎖,另外一個(gè)線程B沒對(duì)文件加鎖

在windows7環(huán)境下:(持有鎖的能夠?qū)懳募晒?。

持有鎖的線程A會(huì)有對(duì)文件的操做權(quán)限,沒加鎖的線程B沒有對(duì)文件的操做權(quán)限,會(huì)報(bào)錯(cuò)退出,以下:linux

java.io.IOException: 另外一個(gè)程序已鎖定文件的一部分,進(jìn)程沒法訪問。

在linux centos 6.3環(huán)境下:(均可以寫文件成功,表現(xiàn)為數(shù)據(jù)交叉寫入)

互不影響,線程A和B都有對(duì)文件的操做權(quán)限web

第二種狀況兩個(gè)線程都有加鎖

在windows7環(huán)境和linux centos 6.3環(huán)境下表現(xiàn)同樣:(持有鎖的能夠?qū)懳募晒?

一個(gè)線程A競(jìng)爭(zhēng)到鎖,會(huì)有對(duì)文件的操做權(quán)限,另外一個(gè)線程B沒有競(jìng)爭(zhēng)到鎖,沒有對(duì)文件的操做權(quán)限,會(huì)報(bào)錯(cuò)退出,而不是發(fā)生阻塞。以下:shell

java.nio.channels.OverlappingFileLockException

在高并的這種生產(chǎn)狀況下,須要捕獲這個(gè)異常,并處理,以下:windows

while (true) {

try {

flout = fcout.tryLock();

break;

} catch (Exception e) {

//計(jì)數(shù)等其余操做...

sleep(1000);

}

}

多進(jìn)程同時(shí)寫一個(gè)文件

若是同為java進(jìn)程,則是不一樣的JVM。不能夠共享內(nèi)存centos

若是同為java進(jìn)程,一個(gè)進(jìn)程A有對(duì)文件加鎖,另外一個(gè)進(jìn)程B沒對(duì)文件加鎖

在windows7環(huán)境下:(持有鎖的能夠?qū)懳募晒?。

持有鎖的進(jìn)程 A會(huì)有對(duì)文件的操做權(quán)限,沒加鎖的進(jìn)程 B沒有對(duì)文件的操做權(quán)限,會(huì)報(bào)錯(cuò)退出,以下:服務(wù)器

java.io.IOException: 另外一個(gè)程序已鎖定文件的一部分,進(jìn)程沒法訪問。

在linux centos 6.3環(huán)境下:(均可以寫文件成功,表現(xiàn)為數(shù)據(jù)交叉寫入)

互不影響,進(jìn)程A和B都有對(duì)文件的操做權(quán)限多線程

若是同為java進(jìn)程,兩個(gè)進(jìn)程都加鎖

在windows7環(huán)境和linux centos 6.3環(huán)境下表現(xiàn)同樣:

誰(shuí)先得到鎖,誰(shuí)先得到對(duì)文件的操做權(quán)限,另外一個(gè)進(jìn)程則會(huì)等待第一個(gè)進(jìn)程處理完成,才會(huì)得到鎖,再對(duì)文件進(jìn)行處理。在這里是發(fā)生阻塞,而不是拋出異常(注意與多線程加鎖的區(qū)別)。

由此能夠證實(shí):針對(duì)對(duì)多進(jìn)程同時(shí)操做同一個(gè)文件,在這里應(yīng)該是底層JVM層面或者本地方法接口庫(kù)對(duì)這個(gè)文件進(jìn)行了加鎖。并發(fā)

一個(gè)為java進(jìn)程,另外一個(gè)為非Java進(jìn)程

此處操做全在服務(wù)器centos6.3上測(cè)試,非Java進(jìn)程為簡(jiǎn)單的 shell 進(jìn)程,例如:

for((i=1;i<10;i++));do echo 333 >> tmp.txt;sleep 1; done

java進(jìn)程無(wú)鎖的狀況

互不影響,java進(jìn)程和非java進(jìn)程都有對(duì)文件的操做權(quán)限

java進(jìn)程無(wú)鎖的狀況

互不影響,java進(jìn)程和非java進(jìn)程都有對(duì)文件的操做權(quán)限

總結(jié)

因而可知,在java高并發(fā)(不管是多線程仍是多進(jìn)程)同時(shí)操做文件時(shí)。

若是沒有文件順序的限制,能夠不加鎖,在這里有操做系統(tǒng)為咱們兜底(這里有風(fēng)險(xiǎn),是否是全部的操做系統(tǒng)都為咱們兜底呢)不會(huì)產(chǎn)生臟數(shù)據(jù);

若是有文件順序要求的限制,在這里不管是多線程仍是多進(jìn)程(前提是Java服務(wù)),均可以獲得很好的并發(fā)控制

若是能夠接受加鎖的開銷和復(fù)雜度,只要遇到并發(fā)操做文件時(shí)均可以加鎖。這樣能夠保證100%不會(huì)亂序,不用考慮是否操做系統(tǒng)會(huì)不會(huì)為咱們兜底了。

若是是使用FileLock try() 方法,同進(jìn)程內(nèi)的多線程訪問, lock會(huì)直接報(bào)OverlappingFileLockException, 而不是一直阻塞。 若是是多進(jìn)程, lock會(huì)一直阻塞,而不會(huì)包OverlappingFileLockException

這代表java提供的FileLock是面向整個(gè)虛擬機(jī)的,即進(jìn)程級(jí)別的。合理利用FileLock,加上多線程的異常處理控制。就能夠在多線程和多進(jìn)程場(chǎng)景下實(shí)現(xiàn)對(duì)文件的高并發(fā)訪問控制

FileLock 做用于java的進(jìn)程級(jí)別,不管獨(dú)占鎖、共享鎖都是針對(duì)不一樣的進(jìn)程,線程之間不適用。

測(cè)試代碼

package com.dxm.etl.test;

import java.io.*;

import java.nio.channels.FileChannel;

import java.nio.channels.FileLock;

public class TestFileLock {

public static void main(String args[]) throws Exception {

System.out.println(Thread.currentThread().getName());

// new ThreadWriteFileWithoutLock("111").start();

// Thread.sleep(1000);

new ThreadWriteFileWithLock("222").start();

}

private static class ThreadWriteFileWithLock extends Thread {

private String threadName;

public ThreadWriteFileWithLock(String threadName) {

this.threadName = threadName;

}

public void run() {

long t1 = System.currentTimeMillis();

File file = new File("tmp.txt");

FileOutputStream output = null;

BufferedWriter br = null;

FileChannel fileChannel = null;

try {

output = new FileOutputStream(file, true);

br = new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));

//對(duì)該文件加鎖

fileChannel = output.getChannel();

FileLock fileLock = null;

fileLock = fileChannel.lock(0,Long.MAX_VALUE,false);

System.out.println(fileLock);

System.out.println(fileLock.isShared());

//非阻塞

/*while (true) {

try {

flout = fcout.tryLock();

break;

} catch (Exception e) {

System.out.println("有其余線程正在操做該文件,當(dāng)前線程休眠1000毫秒");

sleep(1000);

}

}*/

for (int i = 1; i <= 10; i++) {

sleep(1000);

br.write(threadName+"\n");

br.flush();

}

fileLock.release();

} catch (Exception e) {

e.printStackTrace();

System.out.println(threadName +" err");

} finally {

try {

br.close();

fileChannel.close();

output.close();

} catch (IOException e) {

e.printStackTrace();

}

}

System.out.println(threadName + "有鎖,寫文件共花了" + (System.currentTimeMillis() - t1) + "ms");

}

}

public static class ThreadWriteFileWithoutLock extends Thread {

private String threadName;

public ThreadWriteFileWithoutLock(String threadName) {

this.threadName = threadName;

}

public void run() {

long t1 = System.currentTimeMillis();

File file = new File("tmp.txt");

FileOutputStream output = null;

BufferedWriter br = null;

try {

output = new FileOutputStream(file, true);

br = new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));

for (int i = 1; i <= 10; i++) {

sleep(1000);

br.write(threadName+"\n");

br.flush();

}

} catch (Exception e) {

e.printStackTrace();

System.out.println(threadName +" err");

} finally {

try {

br.close();

output.close();

} catch (IOException e) {

e.printStackTrace();

}

}

System.out.println(threadName + "無(wú)鎖,寫文件共花了" + (System.currentTimeMillis() - t1) + "ms");

}

}

}

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的java 多进程写一个文件_java高并发多线程及多进程同时写入文件研究的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。