乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       昵稱2807 2007-09-26

      多線程并發(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ǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多