Java多線程 實(shí)例解析
Java多線程實(shí)例 3種實(shí)現(xiàn)方法
Java中的多線程有三種實(shí)現(xiàn)方式:
1.繼承Thread類,重寫run方法。Thread本質(zhì)上也是一個(gè)實(shí)現(xiàn)了Runnable的實(shí)例,他代表一個(gè)線程的實(shí)例,并且啟動(dòng)線程的唯一方法就是通過Thread類的start方法。
2.實(shí)現(xiàn)Runnable接口,并實(shí)現(xiàn)該接口的run()方法.創(chuàng)建一個(gè)Thread對象,用實(shí)現(xiàn)的Runnable接口的對象作為參數(shù)實(shí)例化Thread對象,調(diào)用此對象的start方法。
3.實(shí)現(xiàn)Callable接口,重寫call方法。Callable接口與Runnable接口的功能類似,但提供了比Runnable更強(qiáng)大的功能。有以下三點(diǎn)
1).Callable可以在人物結(jié)束后提供一個(gè)返回值,Runnable沒有提供這個(gè)功能。
2).Callable中的call方法可以拋出異常,而Runnable的run方法不能拋出異常。
3).運(yùn)行Callable可以拿到一個(gè)Future對象,表示異步計(jì)算的結(jié)果,提供了檢查計(jì)算是否完成的方法。
需要注意的是,無論用那種方式實(shí)現(xiàn)了多線程,調(diào)用start方法并不意味著立即執(zhí)行多線程代碼,而是使得線程變?yōu)榭蛇\(yùn)行狀態(tài)。
run start的區(qū)別
start方法是啟動(dòng)一個(gè)線程,而線程中的run方法來完成實(shí)際的操作。
如果開發(fā)人員直接調(diào)用run方法,那么就會將這個(gè)方法當(dāng)作一個(gè)普通函數(shù)來調(diào)用,并沒有多開辟線程,開發(fā)人員如果希望多線程異步執(zhí)行,則需要調(diào)用start方法。
sleep wait的區(qū)別
1.兩者處理的機(jī)制不同,sleep方法主要是,讓線程暫停執(zhí)行一段時(shí)間,時(shí)間一到自動(dòng)恢復(fù),并不會釋放所占用的鎖,當(dāng)調(diào)用wait方法以后,他會釋放所占用的對象鎖,等待其他線程調(diào)用notify方法才會再次醒來。
2.sleep是Threa的靜態(tài)方法,是用來控制線程自身流程的,而wait是object的方法,用于進(jìn)行線程通信。
3.兩者使用的區(qū)域不同。sleep可以在任何地方使用,wait必須放在同步控制方法,或者語句塊中執(zhí)行。
synchronized notify wait的運(yùn)用
synchronized關(guān)鍵字有兩種用法,synchronized方法和synchronized語句塊。
public synchronized void function(){}
synchronized(object){}
當(dāng)某個(gè)資源被synchronized所修飾,線程1線程2等多個(gè)線程在共同請求這個(gè)資源,線程1先請求到,調(diào)用了對象的wait方法釋放了對象的鎖,此時(shí)線程2可以對這個(gè)對象進(jìn)行訪問,在工作結(jié)束時(shí)可以調(diào)用對象的notify方法,喚醒等待隊(duì)列中正在等待的線程,此時(shí)被喚醒的線程將會再一次拿到對象鎖,對對象進(jìn)行操作??梢哉{(diào)用notifyAll方法,喚醒等待隊(duì)列中的所有線程。
需要注意的是一個(gè)線程被喚醒不代表立即獲取對象鎖,必須等調(diào)用的線程對象的方法推出synchronized塊釋放對象鎖后,被喚醒的進(jìn)程才會獲得對象鎖。
以下為大家提供一個(gè)簡單的代碼實(shí)例:
分別用Runnable和Thread方法實(shí)現(xiàn),展示各個(gè)方法的
實(shí)現(xiàn)Runnable實(shí)現(xiàn)多線程的方法
public class TestRunnable implements Runnable { private int time=1; private SourceA s; private String id = "001"; public TestRunnable(SourceA s){ this.s = s; } public void setTime(int time) { this.time = time; } @Override public void run() { try { System.out.println("i will sleep"+ time); Thread.sleep(time); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized(s){ s.notify(); System.out.println("我喚醒了002!"); System.out.println("我存入了id"+id); s.setSource(id); } } }
繼承Thread實(shí)現(xiàn)多線程的方法
public class TestThread extends Thread { private int time = 1; private SourceA s = null; String id = "002"; public void setTime(int time) { this.time = time; } public TestThread(SourceA s){ this.s = s ; } @Override public void run() { try { System.out.println("i will sleep"+ time); sleep(time); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized(s){ try { System.out.println("我"+ id +"要進(jìn)行等待了"); s.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("我被喚醒了"); System.out.println("我存入了id"+id); s.setSource(id); } } }
SourceA類代碼:
public class SourceA { private List<String> list = new ArrayList<String>(); public synchronized void getSource(){ for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } public synchronized void setSource(String id){ list.add(id); } }
Test測試類代碼:
public void test(){ SourceA s = new SourceA(); TestThread tt = new TestThread(s); TestRunnable tr = new TestRunnable(s); Thread t = new Thread(tr); System.out.println("調(diào)用線程1"); tt.start(); System.out.println("調(diào)用線程2"); t.start(); }
結(jié)果圖片:
- java通過共享變量結(jié)束run停止線程的方法示例
- Java實(shí)現(xiàn)在不同線程中運(yùn)行的代碼實(shí)例
- java多線程之定時(shí)器Timer的使用詳解
- java 實(shí)現(xiàn)線程同步的方式有哪些
- Java多線程的用法詳解
- 15個(gè)高級Java多線程面試題及回答
- java基本教程之java線程等待與java喚醒線程 java多線程教程
- Java線程中斷的本質(zhì)深入理解
- JAVA中 終止線程的方法介紹
- java多線程和并發(fā)包入門示例
- 圖解Java線程的生命周期
- JAVA生產(chǎn)者消費(fèi)者(線程同步)代碼學(xué)習(xí)示例
- Java通過在主循環(huán)中判斷Boolean來停止線程的方法示例
相關(guān)文章
Spring?Cache?集成?Caffeine實(shí)現(xiàn)項(xiàng)目緩存的示例
本文主要介紹了Spring?Cache?集成?Caffeine實(shí)現(xiàn)項(xiàng)目緩存的示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12SpringBoot數(shù)據(jù)校驗(yàn)及多環(huán)境配置的問題詳解
這篇文章主要介紹了SpringBoot數(shù)據(jù)校驗(yàn)及多環(huán)境配置,本文以SpringBoot-02-Config 項(xiàng)目為例,給大家詳細(xì)介紹,需要的朋友可以參考下2021-09-09java ant 配置及構(gòu)建項(xiàng)目圖文教程
以下是對java ant配置及構(gòu)建項(xiàng)目進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下2013-08-08SpringBoot中使用Servlet的兩種方式小結(jié)
這篇文章主要介紹了SpringBoot中使用Servlet的兩種方式小結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07