Java多線(xiàn)程 實(shí)例解析
Java多線(xiàn)程實(shí)例 3種實(shí)現(xiàn)方法
Java中的多線(xiàn)程有三種實(shí)現(xiàn)方式:
1.繼承Thread類(lèi),重寫(xiě)run方法。Thread本質(zhì)上也是一個(gè)實(shí)現(xiàn)了Runnable的實(shí)例,他代表一個(gè)線(xiàn)程的實(shí)例,并且啟動(dòng)線(xiàn)程的唯一方法就是通過(guò)Thread類(lèi)的start方法。
2.實(shí)現(xiàn)Runnable接口,并實(shí)現(xiàn)該接口的run()方法.創(chuàng)建一個(gè)Thread對(duì)象,用實(shí)現(xiàn)的Runnable接口的對(duì)象作為參數(shù)實(shí)例化Thread對(duì)象,調(diào)用此對(duì)象的start方法。
3.實(shí)現(xiàn)Callable接口,重寫(xiě)call方法。Callable接口與Runnable接口的功能類(lèi)似,但提供了比Runnable更強(qiáng)大的功能。有以下三點(diǎn)
1).Callable可以在人物結(jié)束后提供一個(gè)返回值,Runnable沒(méi)有提供這個(gè)功能。
2).Callable中的call方法可以?huà)伋霎惓?,而Runnable的run方法不能拋出異常。
3).運(yùn)行Callable可以拿到一個(gè)Future對(duì)象,表示異步計(jì)算的結(jié)果,提供了檢查計(jì)算是否完成的方法。
需要注意的是,無(wú)論用那種方式實(shí)現(xiàn)了多線(xiàn)程,調(diào)用start方法并不意味著立即執(zhí)行多線(xiàn)程代碼,而是使得線(xiàn)程變?yōu)榭蛇\(yùn)行狀態(tài)。
run start的區(qū)別
start方法是啟動(dòng)一個(gè)線(xiàn)程,而線(xiàn)程中的run方法來(lái)完成實(shí)際的操作。
如果開(kāi)發(fā)人員直接調(diào)用run方法,那么就會(huì)將這個(gè)方法當(dāng)作一個(gè)普通函數(shù)來(lái)調(diào)用,并沒(méi)有多開(kāi)辟線(xiàn)程,開(kāi)發(fā)人員如果希望多線(xiàn)程異步執(zhí)行,則需要調(diào)用start方法。
sleep wait的區(qū)別
1.兩者處理的機(jī)制不同,sleep方法主要是,讓線(xiàn)程暫停執(zhí)行一段時(shí)間,時(shí)間一到自動(dòng)恢復(fù),并不會(huì)釋放所占用的鎖,當(dāng)調(diào)用wait方法以后,他會(huì)釋放所占用的對(duì)象鎖,等待其他線(xiàn)程調(diào)用notify方法才會(huì)再次醒來(lái)。
2.sleep是Threa的靜態(tài)方法,是用來(lái)控制線(xiàn)程自身流程的,而wait是object的方法,用于進(jìn)行線(xiàn)程通信。
3.兩者使用的區(qū)域不同。sleep可以在任何地方使用,wait必須放在同步控制方法,或者語(yǔ)句塊中執(zhí)行。
synchronized notify wait的運(yùn)用
synchronized關(guān)鍵字有兩種用法,synchronized方法和synchronized語(yǔ)句塊。
public synchronized void function(){}
synchronized(object){}
當(dāng)某個(gè)資源被synchronized所修飾,線(xiàn)程1線(xiàn)程2等多個(gè)線(xiàn)程在共同請(qǐng)求這個(gè)資源,線(xiàn)程1先請(qǐng)求到,調(diào)用了對(duì)象的wait方法釋放了對(duì)象的鎖,此時(shí)線(xiàn)程2可以對(duì)這個(gè)對(duì)象進(jìn)行訪(fǎng)問(wèn),在工作結(jié)束時(shí)可以調(diào)用對(duì)象的notify方法,喚醒等待隊(duì)列中正在等待的線(xiàn)程,此時(shí)被喚醒的線(xiàn)程將會(huì)再一次拿到對(duì)象鎖,對(duì)對(duì)象進(jìn)行操作。可以調(diào)用notifyAll方法,喚醒等待隊(duì)列中的所有線(xiàn)程。
需要注意的是一個(gè)線(xiàn)程被喚醒不代表立即獲取對(duì)象鎖,必須等調(diào)用的線(xiàn)程對(duì)象的方法推出synchronized塊釋放對(duì)象鎖后,被喚醒的進(jìn)程才會(huì)獲得對(duì)象鎖。
以下為大家提供一個(gè)簡(jiǎn)單的代碼實(shí)例:
分別用Runnable和Thread方法實(shí)現(xiàn),展示各個(gè)方法的
實(shí)現(xiàn)Runnable實(shí)現(xiàn)多線(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)多線(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類(lèi)代碼:
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測(cè)試類(lèi)代碼:
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)用線(xiàn)程1");
tt.start();
System.out.println("調(diào)用線(xiàn)程2");
t.start();
}
結(jié)果圖片:

- java通過(guò)共享變量結(jié)束run停止線(xiàn)程的方法示例
- Java實(shí)現(xiàn)在不同線(xiàn)程中運(yùn)行的代碼實(shí)例
- java多線(xiàn)程之定時(shí)器Timer的使用詳解
- java 實(shí)現(xiàn)線(xiàn)程同步的方式有哪些
- Java多線(xiàn)程的用法詳解
- 15個(gè)高級(jí)Java多線(xiàn)程面試題及回答
- java基本教程之java線(xiàn)程等待與java喚醒線(xiàn)程 java多線(xiàn)程教程
- Java線(xiàn)程中斷的本質(zhì)深入理解
- JAVA中 終止線(xiàn)程的方法介紹
- java多線(xiàn)程和并發(fā)包入門(mén)示例
- 圖解Java線(xiàn)程的生命周期
- JAVA生產(chǎn)者消費(fèi)者(線(xiàn)程同步)代碼學(xué)習(xí)示例
- Java通過(guò)在主循環(huán)中判斷Boolean來(lái)停止線(xiàn)程的方法示例
相關(guān)文章
mysql高版本(8.0+)group_by報(bào)錯(cuò)的處理方法
本文主要介紹了mysql高版本(8.0+)group_by報(bào)錯(cuò)的處理方法,這個(gè)錯(cuò)誤一般發(fā)生在mysql 5.7以及 5.7以上的版本中,本文就來(lái)介紹一下兩種解決方法,感興趣的可以了解一下2023-09-09
myBatis實(shí)現(xiàn)三級(jí)嵌套復(fù)雜對(duì)象的賦值問(wèn)題
這篇文章主要介紹了myBatis實(shí)現(xiàn)三級(jí)嵌套復(fù)雜對(duì)象的賦值問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
Java?JVM虛擬機(jī)調(diào)優(yōu)詳解
JVM是JavaVirtualMachine(Java虛擬機(jī))的縮寫(xiě),JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的,本文主要介紹了jvm調(diào)優(yōu),感興趣的小伙伴們可以參考一下<BR>2022-07-07
Springboot配置過(guò)濾器實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了Springboot配置過(guò)濾器實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
詳解Spring Cloud Gateway 數(shù)據(jù)庫(kù)存儲(chǔ)路由信息的擴(kuò)展方案
這篇文章主要介紹了詳解Spring Cloud Gateway 數(shù)據(jù)庫(kù)存儲(chǔ)路由信息的擴(kuò)展方案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-11-11

