日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线程同步有几种方法_架构师面试必问的多线程状态切换及常用方法

發布時間:2025/3/12 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程同步有几种方法_架构师面试必问的多线程状态切换及常用方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

架構師面試必問的多線程狀態切換及常用方法

一、問題背景

Java架構師面試中,多線程狀態切換及常用方法幾乎是必問的,要掌握創建多線程的方式和方法。

二、創建多線程的幾種方式

2.1方式一繼承Thread

public class ThreadDemo extends Thread{

public void run()

{

}

}

直接繼承Thread可以創建線程

2.2方式二實現Runnable接口

通過實現Runnable接口,實現創建

public class Thread1 implements Runnable{

public void run()

{

}

}

new Thread(new Thread1()).start();

2.3方式三Callable接口的實現

Callable接口實現了多線程帶有返回值,線程運行可以返回結果值

class ThreadDemo implements Callable {

@Override

public Integer call() throws Exception {

int num= 0;

for (int i = 0; i <= 1000; i++) {

num+= i;

}

return num;

}

}

帶有返回值

ThreadDemo td = new ThreadDemo();

//1.執行 Callable 方式,需要 FutureTask 實現類的支持,用于接收運算結果。

FutureTask result = new FutureTask<>(td);

new Thread(result).start();

//2.接收線程運算后的結果

try {

Integer sum = result.get(); //FutureTask 可用于 閉鎖 類似于CountDownLatch的作用,在所有的線程沒有執行完成之后這里是不會執行的

System.out.println(sum);

System.out.println("------------------------------------");

} catch (InterruptedException | ExecutionException e) {

e.printStackTrace();

}

線程result.get就是返回的結果值

三、多線程的生命周期

運行狀態轉換

Java線程具有五種基本狀態

新建狀態(New):當線程對象對創建后,即進入了新建狀態,如:Thread t = new CallThread();

就緒狀態(Runnable):當調用線程對象的start()方法(t.start();),線程即進入就緒狀態。處于就緒狀態的線程,只是說明此線程已經做好了準備,隨時等待CPU調度執行,并不是說執行了t.start()此線程立即就會執行;

運行狀態(Running):當CPU開始調度處于就緒狀態的線程時,此時線程才得以真正執行,即進入到運行狀態。注:就 緒狀態是進入到運行狀態的唯一入口,也就是說,線程要想進入運行狀態執行,首先必須處于就緒狀態中;

阻塞狀態(Blocked):處于運行狀態中的線程由于某種原因,暫時放棄對CPU的使用權,停止執行,此時進入阻塞狀態,直到其進入到就緒狀態,才 有機會再次被CPU調用以進入到運行狀態。根

3.1幾種阻塞狀態

據阻塞產生的原因不同,阻塞狀態又可以分為三種:

1.等待阻塞:運行狀態中的線程執行wait()方法,使本線程進入到等待阻塞狀態;

2.同步阻塞 -- 線程在獲取synchronized同步鎖失敗(因為鎖被其它線程所占用),它會進入同步阻塞狀態;

3.其他阻塞 -- 通過調用線程的sleep()或join()或發出了I/O請求時,線程會進入到阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。

3.2結束生命周期

死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命周期。

3.3就緒、運行與死亡狀態之間的切換

當多線程獲得了處理器CPU資源,就從就緒狀態躍遷為運行狀態;

當多線程調用yield方法,多線程就從運行狀態變為就緒狀態;

當一個線程執行完了或遇到Exception就變為死亡狀態;

四、如何中止線程

使用Java原子變量volatile表示,一次只有一個線程能使用此狀態。如下,當volatile變量改變時,可以終止線程

public class MainThread extends Thread {

//volatile修飾符用來保證其它線程讀取的總是該變量的最新的值

public volatile boolean exit = false;

@Override

public void run() {

ServerSocket mainSocket = new ServerSocket(1090);

while(!exit){

mainSocket.accept(); //阻塞等待

...

}

}

使用stop可以終止線程,但是會造成線程不安全。stop會立刻停止run方法中的數據,包括catch和finally中的語句塊,會造成異常,導致文件數據庫得不到關閉。

使用interupt中斷線程,是線程安全的,不會立即結束線程,只是通知線程,提前告知:

try {

InterruptFGThread1 t = new InterruptFGThread1();

t.start();

Thread.sleep(1000);

t.interrupt();

} catch (InterruptedException e) {

e.printStackTrace();

}

public void run() {

super.run();

for(int i = 0; i <= 5000; i++) {

System.out.println("i=" + i);

}

}

設置了中斷狀態,但中斷不會起作用,此時得用到isInterrupted方法來終止線程

public void run() {

f();

for(int i = 0; i <= 5000; i++) {

//判斷是否被中斷

if(Thread.currentThread().isInterrupted()){

//處理中斷邏輯

break;

}

System.out.println("i=" + i);

}

當線程感知到interrupt中斷時,會通過isInterrupted()進行終止程序控制操作,可以控制。

Interrupt與Stop相比,線程安全,程序可控,并不實際終止線程。

五、sleep與wait方法的區別

sleep來自Thread類,和wait來自Object類。

sleep不出讓系統資源;wait是進入線程等待池等待,出讓系統資源,其他線程可以占用CPU。一般wait不會加時間限制,因為如果wait線程的運行資源不夠,再出來也沒用,要等待其他線程調用notify/notifyAll喚醒等待池中的所有線程,才會進入就緒隊列等待OS分配系統資源。

5.1wait方法只限于同步鎖狀態中

wait用于Object對象,發出wait后。可以通過notify和notifyAll來喚醒線程。但是只能用于synchronized同步塊中

synchronized(obj){

obj.notify()

//或者obj.wait()

}

5.2異常

sleep方法必須捕獲異常

try{

sleep(500);

}catch(Exception e)

{

log.error();

}

wait方法無需捕獲異常,作用于Object

使用wait后,采用notify與notifyAll喚醒從而變為運行狀態

多線程常見于面試中,一定要注意。

總結

以上是生活随笔為你收集整理的线程同步有几种方法_架构师面试必问的多线程状态切换及常用方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。