免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
多線程并發(fā)思考--文件加鎖

多線程并發(fā)思考--文件加鎖

         在最近的工作中,經(jīng)常要用到線程,就對線程相關(guān)知識稍微看了看,知道并發(fā)線程經(jīng)常引起共享資源沖突,java以提供關(guān)鍵字synchronized的形式,為防止資源沖突提供了內(nèi)置支持.

         可是在工作中,我卻碰到了這樣的需求,定時拋出線程讀寫某文件的內(nèi)容,由于相隔時間很短,我突然想到,會不會在第二次輪循開始對該文件進行讀操作的時候,第一次拋出的線程還在對該文件進行寫操作,如果有可能,那么第二次讀出的數(shù)據(jù)會是什么樣的呢?

        懷著這樣的疑問,我開始以程序作實驗,代碼如下:

1.用于寫文件的線程

package chb.thread;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;

/**
 * 
@author 崔紅保
 *  
 *  這個線程用于寫文件
 
*/

public class Thread_writeFile extends Thread{
    
public void run(){
        Calendar calstart
=Calendar.getInstance();
        File file
=new File("D:/test.txt");    
        
try {
            
if(!file.exists())
                file.createNewFile();
            FileWriter fw
=new FileWriter(file);
            BufferedWriter bw
=new BufferedWriter(fw);
            
for(int i=0;i<1000;i++){
                sleep(
10);
                bw.write(
"這是第"+(i+1)+"行,應(yīng)該沒錯哈 ");
            }

            bw.close();
            bw
=null;
            fw.close();
            fw
=null;
        }
 catch (IOException e) {
            e.printStackTrace();
        }
 catch (InterruptedException e) {
            e.printStackTrace();
        }

        Calendar calend
=Calendar.getInstance();
        System.out.println(
"寫文件共用了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"毫秒");
    }


}

2.用于讀文件的線程

package chb.thread;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Calendar;

/**
 * 
@author 崔紅保
 *
 *這個線程用于讀文件
 
*/

public class Thread_readFile extends Thread{
    
public void run(){
        
try {
            Calendar calstart
=Calendar.getInstance();
            sleep(
5000);
            File file
=new File("D:/test.txt");    
            BufferedReader br
=new BufferedReader(new FileReader(file));
            String temp
=null;
            temp
=br.readLine();
            
while(temp!=null){
                System.out.println(temp);
                temp
=br.readLine();
            }

            
            br.close();
            br
=null;
            Calendar calend
=Calendar.getInstance();
            System.out.println(
"讀文件共用了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"毫秒");
        }
catch (FileNotFoundException e) {
            e.printStackTrace();
        }
 catch (IOException e) {
            e.printStackTrace();
        }
 catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

3.分別啟用兩個線程

        Thread_writeFile thf3=new Thread_writeFile();
        Thread_readFile thf4
=new Thread_readFile();
        thf3.start();
        thf4.start();

4.結(jié)果分析

雖然寫文件的操作開始5秒鐘后,讀文件的操作才開始進行,可是讀文件的線程并沒有讀出數(shù)據(jù),改變時間,讀出的數(shù)據(jù)也就各不相同.

         為了避免以上結(jié)果,我們希望在一個線程在操作某個文件的時候,其他線程不能對該文件進行讀或?qū)懖僮?要怎么才能實現(xiàn)呢?利用java提供的synchronized似乎無法完成,因為每個線程是在程序中動態(tài)拋出的.郁昧了一天之后,我終于找到了一個解決辦法,就是利用java.nio包中的FileChannel對文件進行加鎖.

         具體實現(xiàn)方法如下:

1.寫文件的線程

package chb.thread;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Calendar;

/**
 * 
@author chb
 *
 
*/

public class Thread_writeFile extends Thread{
    
public void run(){
        Calendar calstart
=Calendar.getInstance();
        File file
=new File("D:/test.txt");        
        
try {
            
if(!file.exists())
                file.createNewFile();
                        
            
//對該文件加鎖
            FileOutputStream out=new FileOutputStream(file,true);
            FileChannel fcout
=out.getChannel();
            FileLock flout
=null;
            
while(true){
                flout
=fcout.tryLock();
                
if(flout!=null){
                    
break;
                }

                
else{
                    System.out.println(
"有其他線程正在操作該文件,當(dāng)前線程休眠1000毫秒");
                    sleep(
100);
                }

            }

        
            
for(int i=1;i<=1000;i++){
                sleep(
10);
                StringBuffer sb
=new StringBuffer();
                sb.append(
"這是第"+i+"行,應(yīng)該沒啥錯哈 ");
                out.write(sb.toString().getBytes(
"utf-8"));
            }


            
            flout.release();
            fcout.close();
            out.close();
            out
=null;
        }
 catch (IOException e) {
            e.printStackTrace();
        }
 catch (InterruptedException e) {
            e.printStackTrace();
        }

        Calendar calend
=Calendar.getInstance();
        System.out.println(
"寫文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"");
    }

}

2.讀文件的線程

package chb.thread;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Calendar;

/**
 * 
@author chb
 * ?????
 
*/

public class Thread_readFile extends Thread{
    
public void run(){
        
try {
            Calendar calstart
=Calendar.getInstance();
            sleep(
5000);
            File file
=new File("D:/test.txt");    
            
            
//給該文件加鎖
            FileInputStream fis=new FileInputStream(file);
            FileChannel fcin
=fis.getChannel();
            FileLock flin
=null;
            
while(true){
                flin
=fcin.tryLock(0,Long.MAX_VALUE,true);
                
if(flin!=null){
                    
break;
                }

                
else{
                    System.out.println(
"有其他線程正在操作該文件,當(dāng)前線程休眠1000毫秒");
                    sleep(
1000);
                }

            }

            
byte[] buf = new byte[1024];
            StringBuffer sb
=new StringBuffer();
            
while((fis.read(buf))!=-1){                
                sb.append(
new String(buf,"utf-8"));    
                buf 
= new byte[1024];
            }

            
            System.out.println(sb.toString());
            
            flin.release();
            fcin.close();
            fis.close();
            fis
=null;
            
            Calendar calend
=Calendar.getInstance();
            System.out.println(
"讀文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"");
        }
catch (FileNotFoundException e) {
            e.printStackTrace();
        }
 catch (IOException e) {
            e.printStackTrace();
        }
 catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

3.分別啟用兩個線程

        Thread_writeFile thf3=new Thread_writeFile();
        Thread_readFile thf4
=new Thread_readFile();
        thf3.start();
        thf4.start();

4.結(jié)果分析

以上程序在對一個文件執(zhí)行寫操作前,先對該文件加鎖,這樣其他線程就不能再對該文件操作,等該線程的寫操作結(jié)束,釋放資源,其他線程才可以繼續(xù)對該文件執(zhí)行相應(yīng)的讀寫操作.

可是,郁昧的是,這段程序在windows下可以正確執(zhí)行,在linux下卻無效.根據(jù)<Thinking in Java>上的觀點是:對獨占鎖或者共享鎖的支持必須由底層的操作系統(tǒng)提供.

          綜觀我的解決方法,總感覺不太完美,各位如有好的方法來判斷一個文件是否正被某個線程使用,希望大家一起分享一下.



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1440226

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java讀取文件加鎖代碼Demo(利用Java的NIO)
snippets/438843 | CODE
Java實現(xiàn)簡單的Socket服務(wù)器與客戶端字符串通訊(適合初學(xué)者閱讀)
初學(xué)者第73節(jié)網(wǎng)絡(luò)編程-ServerSocket(二)
Java基于socket文件傳輸示例
java 文件鎖
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服