java兩個線程同時寫一個文件
本文實例為大家分享了java兩個線程同時寫一個文件的具體代碼,供大家參考,具體內(nèi)容如下
1.多線程
線程是程序執(zhí)行流的最小單元。是進程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創(chuàng)建和撤消另一個線程,同一進程中的多個線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運行三種基本狀態(tài)。就緒狀態(tài)是指線程具備運行的所有條件,邏輯上可以運行,在等待處理機;運行狀態(tài)是指線程占有處理機正在運行;阻塞狀態(tài)是指線程在等待一個事件(如某個信號量),邏輯上不可執(zhí)行。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。
多線程的意義就在于使得一個應(yīng)用程序有多條執(zhí)行路徑,從而提高進程(程序)的執(zhí)行效率。
2.JAVA中的多線程
2.1概述實現(xiàn)
JAVA實現(xiàn)多線程的方法有三種: 1)繼承Thread實現(xiàn)多線程。2)通過實現(xiàn)Runnable接口方式實現(xiàn)多線程。3)使用ExecutorService、Callable、Future實現(xiàn)有返回結(jié)果的多線程。這三種方法的具體實現(xiàn),在此先不一一贅述,網(wǎng)上有很多有關(guān)的博客,不明白的朋友可以去看看。
JAVA程序的運行原理便是命令去啟動JVM,JVM會啟動一個進程,該進程會啟動一個主線程。然而JVM的啟動必然也是多線程的,一般情況下,它最低有兩個線程啟動了:主線程和垃圾回收線程。
2.2線程生命周期
1)新建 2)就緒 3)運行 4)阻塞 5)死亡
2.3線程的優(yōu)先級
線程的調(diào)度有兩種方式:1)分時調(diào)度。2)搶占式調(diào)度。JAVA采用的是后者,默認(rèn)情況下,線程去搶占資源(CPU執(zhí)行權(quán))。我們可以通過setPriority方法,設(shè)置線程的優(yōu)先級,默認(rèn)是5,范圍為1-10。但是一般情況下,光是設(shè)置線程的優(yōu)先級,不能使得線程有序且高效執(zhí)行,所以我們還需要學(xué)習(xí)更多的方法與原理機制。
2.4線程的控制(常見方法)
1)休眠線程 2)加入線程 3)禮讓線程 4)后臺線程 5)終止線程
2.5多線程的安全問題
在多線程的環(huán)境下,大多時候都是會共享數(shù)據(jù),存在多條語句操作共享數(shù)據(jù),這樣很多時候會出現(xiàn)臟數(shù)據(jù)。所以為了解決線程的安全的問題,我們可以通過synchronized同步鎖對象達到我們的目的。
1)同步代碼塊
synchronized(對象) { 需要被同步的代碼塊 }
2)同步方法
把同步加在方法上,這里的鎖對象是this。
3)靜態(tài)同步方法
把同步加在方法上。這里的鎖是當(dāng)前類的字節(jié)碼文件。
PS:JDK5以后的針對線程的鎖定操作和釋放操作: Lock鎖。
3.多線程寫一個文件
如何實現(xiàn)多線程同時或讀或?qū)懸粋€文件呢?我們都知道,一個文件在同一時間只能被一個線程讀(寫),如果要兩個線程同時寫一個文件,如何有效有序的分配這個臨界資源呢?
下面我將通過一個例子,闡述我的解決方法 -——沉睡喚醒機制。
需求:兩個線程寫一個TXT文件,線程1:I love you 線程2:so do I 。保證線程1、2有序執(zhí)行,一句I love you,對應(yīng)一句so do I。
第一步,先創(chuàng)建WRFile類。這一步是關(guān)鍵的。
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(); } } //修改標(biāo)記 喚醒線程 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(); } } //修改標(biāo)記 喚醒線程 this.flag = false; this.notify(); } }
第二步,創(chuàng)建我們的兩個線程類,第一個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) { //創(chuàng)建數(shù)據(jù)對象 WRFile wr = new WRFile(); //設(shè)置和獲取類 FirstThread ft = new FirstThread(wr); SecondThrad st = new SecondThrad(wr); //線程類 Thread th1 = new Thread(ft); Thread th2 = new Thread(st); //啟動線程 th1.start(); th2.start(); } }
即可實現(xiàn)兩個線程同時(有序)寫一個文件,兩個以上,或是其他操作也可參考這種思想去實現(xiàn)。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
spring中向一個單例bean中注入非單例bean的方法詳解
Spring是先將Bean對象實例化之后,再設(shè)置對象屬性,所以會先調(diào)用他的無參構(gòu)造函數(shù)實例化,每個對象存在一個map中,當(dāng)遇到依賴,就去map中調(diào)用對應(yīng)的單例對象,這篇文章主要給大家介紹了關(guān)于spring中向一個單例bean中注入非單例bean的相關(guān)資料,需要的朋友可以參考下2021-07-07SpringBoot2.x中management.security.enabled=false無效的解決
這篇文章主要介紹了SpringBoot2.x中management.security.enabled=false無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07Springboot中使用Filter實現(xiàn)Header認(rèn)證詳解
這篇文章主要介紹了Springboot中使用Filter實現(xiàn)Header認(rèn)證詳解,當(dāng)在?web.xml?注冊了一個?Filter?來對某個?Servlet?程序進行攔截處理時,它可以決定是否將請求繼續(xù)傳遞給?Servlet?程序,以及對請求和響應(yīng)消息是否進行修改,需要的朋友可以參考下2023-08-08關(guān)于SpringBoot攔截器攔截靜態(tài)資源的問題
這篇文章主要介紹了關(guān)于SpringBoot攔截器攔截靜態(tài)資源的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07spring動態(tài)控制定時任務(wù)的實現(xiàn)
在實際項目中,經(jīng)常需要動態(tài)的控制定時任務(wù),比如通過接口增加、啟動、停止、刪除定時任務(wù),本文主要介紹了spring動態(tài)控制定時任務(wù)的實現(xiàn),感興趣的可以了解一下2024-01-01