java兩個線程同時寫一個文件

這篇文章主要爲大家詳細介紹了java兩個線程同時寫一個文件,具有一定的參考價值,感興趣的小夥伴們可以參考一下

本文實例爲大家分享了java兩個線程同時寫一個文件的具體代碼,供大家參考,具體內容如下

1.多線程   

線程是程序執行流的最小單元。是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程自己不擁有系統資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創建和撤消另一個線程,同一進程中的多個線程之間可以併發執行。由於線程之間的相互制約,致使線程在運行中呈現出間斷性。線程也有就緒、阻塞和運行三種基本狀態。就緒狀態是指線程具備運行的所有條件,邏輯上可以運行,在等待處理機;運行狀態是指線程佔有處理機正在運行;阻塞狀態是指線程在等待一個事件(如某個信號量),邏輯上不可執行。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。

多線程的意義就在於使得一個應用程序有多條執行路徑,從而提高進程(程序)的執行效率。

2.JAVA中的多線程

2.1概述實現

JAVA實現多線程的方法有三種: 1)繼承Thread實現多線程。2)通過實現Runnable接口方式實現多線程。3)使用ExecutorService、Callable、Future實現有返回結果的多線程。這三種方法的具體實現,在此先不一一贅述,網上有很多有關的博客,不明白的朋友可以去看看。

JAVA程序的運行原理便是命令去啓動JVM,JVM會啓動一個進程,該進程會啓動一個主線程。然而JVM的啓動必然也是多線程的,一般情況下,它最低有兩個線程啓動了:主線程和垃圾回收線程。

2.2線程生命週期

1)新建        2)就緒        3)運行        4)阻塞        5)死亡

2.3線程的優先級

線程的調度有兩種方式:1)分時調度。2)搶佔式調度。JAVA採用的是後者,默認情況下,線程去搶佔資源(CPU執行權)。我們可以通過setPriority方法,設置線程的優先級,默認是5,範圍爲1-10。但是一般情況下,光是設置線程的優先級,不能使得線程有序且高效執行,所以我們還需要學習更多的方法與原理機制。

2.4線程的控制(常見方法)

1)休眠線程        2)加入線程        3)禮讓線程        4)後臺線程        5)終止線程

2.5多線程的安全問題

在多線程的環境下,大多時候都是會共享數據,存在多條語句操作共享數據,這樣很多時候會出現髒數據。所以爲了解決線程的安全的問題,我們可以通過synchronized同步鎖對象達到我們的目的。

1)同步代碼塊

synchronized(對象)

{

 需要被同步的代碼塊
}

2)同步方法

把同步加在方法上,這裏的鎖對象是this。

3)靜態同步方法

把同步加在方法上。這裏的鎖是當前類的字節碼文件。

PS:JDK5以後的針對線程的鎖定操作和釋放操作: Lock鎖。

3.多線程寫一個文件

如何實現多線程同時或讀或寫一個文件呢?我們都知道,一個文件在同一時間只能被一個線程讀(寫),如果要兩個線程同時寫一個文件,如何有效有序的分配這個臨界資源呢?

下面我將通過一個例子,闡述我的解決方法 -——沉睡喚醒機制。

需求:兩個線程寫一個TXT文件,線程1:I love you  線程2:so do I 。保證線程1、2有序執行,一句I love you,對應一句so do I。

第一步,先創建WRFile類。這一步是關鍵的。

package cn.Thread.love;
 
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
 
public class WRFile {
 //String str;
 boolean flag;
 public WRFile()
 {
 
 }
 public synchronized void read1()
 {
 if(this.flag)
 {
 try {
 this.wait();
 } catch (InterruptedException e) {
 
 e.printStackTrace();
 }
 }
 RandomAccessFile ra = null;
 try {
 ra = new RandomAccessFile("love.txt", "rw");
 ra.seek(ra.length());
 
 ra.writeBytes("I love you");
 ra.writeBytes("\r\n");
 } catch (Exception e) {
 
 e.printStackTrace();
 }
 finally {
 try {
 ra.close();
 } catch (IOException e) {
 
 e.printStackTrace();
 }
 }
 //修改標記 喚醒線程
 this.flag = true;
 this.notify();
 }
 public synchronized void read2()
 {
 if(!this.flag)
 {
 try {
 this.wait();
 } catch (InterruptedException e) {
 
 e.printStackTrace();
 }
 }
 RandomAccessFile ra = null;
 try {
 ra = new RandomAccessFile("love.txt", "rw");
 ra.seek(ra.length());
 
 ra.writeBytes("so do I");
 ra.writeBytes("\r\n");
 } catch (Exception e) {
 
 e.printStackTrace();
 }
 finally {
 try {
 ra.close();
 } catch (IOException e) {
 
 e.printStackTrace();
 }
 }
 //修改標記 喚醒線程
 this.flag = false;
 this.notify();
 }
 
}

第二步,創建我們的兩個線程類,第一個FirstThread。

package cn.Thread.love;
 
public class FirstThread implements Runnable {
private WRFile wr = new WRFile();
 
 public FirstThread(WRFile wr) {
 this.wr = wr;
 } 
 @Override
 public void run() {
 
 while(true)
 {
 wr.read1();
 }
 
 }
 
}

第二個SecondThread

package cn.Thread.love;
 
public class SecondThrad implements Runnable{
 private WRFile wr = new WRFile();
 public SecondThrad(WRFile wr) {
 this.wr = wr;
 }
 @Override
 public void run() {
 while(true)
 {
 wr.read2();
 }
 }
 
 
}

第三步,main方法啓動線程

package cn.Thread.love;
 
public class LoveDemo {
 
 public static void main(String[] args) {
 //創建數據對象
 WRFile wr = new WRFile();
 //設置和獲取類
 FirstThread ft = new FirstThread(wr);
 SecondThrad st = new SecondThrad(wr);
 //線程類
 Thread th1 = new Thread(ft);
 Thread th2 = new Thread(st);
 //啓動線程
 th1.start();
 th2.start();
 }
 
}

即可實現兩個線程同時(有序)寫一個文件,兩個以上,或是其他操作也可參考這種思想去實現。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持神馬文庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章