『壹』 java里多線程的wait問題

喜歡思考絕對是好事,但我希望你對於一個為題你能自己分析的透徹點,wait()當然是線程去等待,線程講的就是電腦的cpu如何工作,而你說的資源了只是數據也就是你給電腦的一種指令,數據有什麼等待的說法嗎?還有你說上面的那個程序不會出來,你那個while的條件是什麼,你都沒吧,如果是死循環那當然不會出來了。

『貳』 新手問個Java中線程wait方法的一個問題

負責任的告訴你 是 主線程在等待。
看 API wait():

在其他線程調用此對象的 notify() 方法或 notifyAll()
方法前,導致當前線程等待。換句話說,此方法的行為就好像它僅執行 wait(0) 調用一樣。
當前線程必須擁有此對象監視器。該線程發布對此監視器的所有權並等待,直到其他線程通過調用 notify 方法,或
notifyAll 方法通知在此對象的監視器上等待的線程醒來。然後該線程將等到重新獲得對監視器的所有權後才能繼續執行。

API 已經很明確說了,導致當前線程等待。

『叄』 Java多線程中await和wait的區別

  1. 調用await/wait的時候卻釋放了其獲取的鎖並阻塞等待。

  2. await/wait,它會一直阻塞在條件隊列之上,之後某個線程調用對應的notify/signal方法,才會使得await/wait的線程回到就緒狀態,也是不一定立即執行。

  3. await/wait方法必須放在同步塊裡面,否則會產生運行時異常。

  4. wait方法是Object類的,await方法是Condition顯示條件隊列的。

『肆』 java如何停止一個wait的線程

java.lang.System類

staticvoidexit(intstatus)
終止當前正在運行的Java虛擬機。

『伍』 誰能幫我解釋一下java線程中的wait()方法的作用與執行原理非常感謝!

wait()方法是java.lang.Object類韋線程提供的用於實現線程間通信的同步控制方法。wait()方法使當前線程主動釋放互斥鎖,並進入該互斥鎖的等待隊列。(也就是說,它使當前線程暫停執行,等待其他線程執行notify()方法或者notifyall()方法後再繼續執行本線程。)本方法用於釋放一個項目的線程,喚醒另一個可能在等待的線程。有兩種調用格式:
1.wait()等待通信線程喚醒後再繼續執行本線程。
2.wait(long millis)等待通信線程喚醒或者最多等待millis毫秒後,再繼續執行本線程。

我知道的就這么多了哈,希望對你能有一點幫助哦~~

『陸』 java里 對線程的wait方法只有在synchronized下才有用嗎

調用 a.wait() 前需要拿到這個 a 對象的鎖,這是必須的,像下面這樣:

Listqueue=newjava.util.LinkedList();

synchronized(queue){
queue.wait();
}

或者在方法上加了 synchronized,然後用對象自己的鎖來等待:

publicsynchronizedbooleanget(){
if(queue.isEmpty()){
this.wait();
}

returnqueue.removeFirst();
}

『柒』 Java線程中wait狀態和block狀態的區別

一、線程5種狀態
新建狀態(New) 新創建了一個線程對象。
就緒狀態(Runnable) 線程對象創建後,其他線程調用了該對象的start()方法。該狀態的線程位於可運行線程池中,變得可運行,等待獲取CPU的使用權。
運行狀態(Running) 就緒狀態的線程獲取了CPU,執行程序代碼
阻塞狀態(Blocked) 阻塞狀態是線程因為某種原因放棄CPU使用權,暫時停止運行。直到線程進入就緒狀態,才有機會轉到運行狀態。阻塞的情況分三種:
等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。
同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則JVM會把該線程放入鎖池中。
其他阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置為阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。
死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命周期。
二、Jstack中常見的線程狀態
應用程序啟動後,我們對系統運行狀況的觀測大部分情況下是通過運行日誌。但是若某一天發現,日誌中記錄的行為與預想的不一致,此時需要進一步的系統監控該怎麼辦,Jstack是常用的排查工具,它能輸出在某一個時間,Java進程中所有線程的狀態,很多時候這些狀態信息能給我們的排查工作帶來有用的線索。 Jstack的輸出中,Java線程狀態主要是以下幾種:
RUNNABLE 線程運行中或I/O等待
BLOCKED 線程在等待monitor鎖(synchronized關鍵字)
TIMED_WAITING 線程在等待喚醒,但設置了時限
WAITING 線程在無限等待喚醒
1) 讓線程一直處於RUNNABLE
public static void runnable() { long i = 0; while (true) { i++; } }

2) 讓線程一直處於BLOCKED
public static void blocked() { final Object lock = new Object(); new Thread() { public void run() { synchronized (lock) { System.out.println("i got lock, but don't release"); try { Thread.sleep(1000L * 1000); } catch (InterruptedException e) { } } } }.start(); try { Thread.sleep(100); } catch (InterruptedException e) {} synchronized (lock) { try { Thread.sleep(30 * 1000); } catch (InterruptedException e) { } } }

主線程sleep,先讓另外一個線程拿到lock,並長期持有lock(sleep會持有鎖,wait不會)。此時主線程會BLOCK住等待lock被釋放,此時jstack的輸出可以看到main線程狀態是BLOCKED。這里要注意的是只有synchronized這種方式的鎖(monitor鎖)才會讓線程出現BLOCKED狀態,等待ReentrantLock則不會。
3) 讓線程處於TIMED_WAITING狀態

public static void timedWaiting() { final Object lock = new Object(); synchronized (lock) { try { lock.wait(30 * 1000); } catch (InterruptedException e) { } } }

1

4)讓線程處於WAITING狀態
public static void waiting() { final Object lock = new Object(); synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { } } }

無超時的等待,必須等待lock.notify()或lock.notifyAll()或接收到interrupt信號才能退出等待狀態。

『捌』 java 線程wait和喚醒

suspend,使線程進入停滯狀態,除非收到resume消息,否則該線程不會變回可執行狀態。
wait():使一個線程處於等待狀態,並且釋放所持有的對象的lock;
sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方 法要捕捉InterruptedException異常;
notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候, 並不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且 不是按優先順序;
notityAll():喚醒所有處入等待狀態的線程,注意並不是給所有喚醒線程一 個對象的鎖,而是讓它們競爭。

『玖』 java 線程中wait和notify的問題

這個程序挺經典的.

我不知道你對wait這是不是很熟,我按我的說,有問題再溝通:

首先看
main函數,兩句話,Procer對象和Consumer對象都引用了同一個p.
Procer類的run
前面有
synchronized(p)
說明該線程用到 synchronized 里的對象變數時,別的線程只能等待.
再看
if(p.bFull) {
try{p.wait();} catch (Exception e) {}
}
也就是說該線程用到了p對象,
而如果當運行到該線程時,
且p.bFull為真時
該線程進行等待,讓其他線程運行

到這的思路如果沒有問題,
那麼我們假設
假設
p.bFull為假,
那麼會再往下運行
也就是設置姓名,性別,
此時p.bFull仍然為假

之後設置 p.bFull 為真
p.notify()
當設置p.bFull為真時,表示下次如果仍然是該線程執行,將會wait.
而p.notify()是為了解以p為鎖的線程,因為當前線程正在運行,所以當前線程肯定不需要解鎖,那可能需要被解鎖的,也就是Consumer對象的線程.

當前線程從開始運行到目前的位置,Consumer線程是一直在wait的,因為Consumer線程在while下面直接就synchronized (p)也就是這兩個線程同時只能一個線程運行.
也就是說,要麼這次運行Procer,要麼運行Consumer
按我上面說的,Procer的運行邏輯應該已經清楚了,而Consumer的線程運行邏輯跟Procer一樣,我就不多說了,

問題的關鍵在於
當Procer運行一次,之後Consumer運行一次,是比較好理解,交叉運行唄.
但如果Procer運行完,又運行了Procer線程,而沒有讓Consumer運行的時候,程序會怎麼運行?(反之一樣)
我下面來解釋.
當Procer運行一次,又運行了Procer時,這時因為沒有Consumer線程的介入
,p的bFull應該為真,
這時運行到
Procer線程的
if (p.bFull) {
try {
p.wait();
} catch (Exception e) {
}
時,因為p.bFull為真了,
所以運行下面的代碼,
也就是讓當前線程等待,而用來等待的鎖就是p
這時,當前線程等待了,
也就要執行Consumer線程了,也就是相當於強制切換線程
運行一次Consumer線程後,Procer仍然在等待,如果這樣,那就會仍然運行Consumer線程,根據邏輯,Consumer會像Procer一樣,由於
if(!p.bFull) {
try{p.wait(); } catch (Exception e) {} }
而等待
這樣兩個線程都等待了
(如果你問,當!p.bFull如果成立,那p.bFull就不成立,那Procer不是該運行了嗎?但是,我剛剛的假設是當Procer已經等待時,那麼Procer就不會因為p.bFull的改變而繼續運行了)

按上面所說,如果按這樣的邏輯,最終會導致兩個線程同時等待沒有解鎖,
為了解決這個問題,
就在程序的每個線程的
p.bFull = false;
後面,加上了
p.notify();
讓以p為鎖的線程解鎖等待.
這樣,就可以使程序的兩個線程來回切換了.