當前位置:首頁 » 編程語言 » java線程的喚醒

java線程的喚醒

發布時間: 2022-11-05 00:01:08

java 多線程子線程喚醒主線程問題

設一個三個線程的共享對象o

a.start(); b.start();//啟動子線程
主線程中
o.wait(10*1000);//主線程中等10秒
同時A、B中各有一個執行完的通知
a或b的run(){
.....
o. notify();
}
基本的線程操作...

Ⅱ java 線程 喚醒問題

首先,從你程序的本意來看, 你是想用線程實現一個生產者-- 消費者模式, 用在饅頭的場景, 如下:

1、 肯定需要一個籃子, 負責裝饅頭,並且這個籃子有容量,假設容量為C;
2、 有兩個人,第一個是爹(生產者), 第二個是娃(消費者), 爹負責向籃子中放入饅頭, 娃負責從籃子中取出饅頭喂狗;
3、 但是籃子的容量是有限的, 當籃子被裝滿時, 爹就等待娃從籃子中取出饅頭,籃子騰出空間之後,爹繼續裝饅頭; 當籃子的饅頭都被取走後, 娃就等待, 當籃子中又被放入饅頭時,才繼續取饅頭。

附上代碼:

籃子:

public class Bucket {
private int count = 0; // 籃子能夠容納的饅頭數
private int total = 0; // 放饅頭的總數

public synchronized void put(){
if(count == 5){
try {
System.out.println("俺是他爹,籃子滿了,俺在等俺家娃拿饅頭喂狗");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

count += 1;
total++;
System.out.println("俺是他爹,俺放了一個饅頭,現有籃子里有 [" + count + "] 個饅頭");
notify();
}

public synchronized boolean get(){
if(count == 0){
try {
wait();
System.out.println("俺是他娃,籃子空了,俺在等俺爹放饅頭到籃子里");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count -= 1;
System.out.println("俺拿了一個饅頭喂俺家大花狗, 籃子里還有 [" + count + "] 個饅頭");
notify();

if(total == 100 && count == 0){
return false;
}else{
return true;
}
}

爹:

public class Proct implements Runnable{

private Bucket bucket;
Proct(Bucket bucket){
this.bucket = bucket;
}

@Override
public void run() {
for(int i=0; i<100; i++){
bucket.put();
}
System.out.println("俺把饅頭都放完了");
}
}

娃:

public class Consumer implements Runnable{

private Bucket bucket;
public Consumer(Bucket bucket){
this.bucket = bucket;
}

@Override
public void run() {
while(true){
if(!bucket.get()){
break;
}
}
System.out.println("俺家大花狗吃完饅頭了");
}

}

啟動類:

public class Test {

public static void main(String[] args) {

Bucket bucket = new Bucket();
new Thread(new Consumer(bucket)).start();
new Thread(new Proct(bucket)).start();
}
}

最後附上你的問題, notify 由誰來喚醒:

注意 wait() 和 notify() 是Object類上的方法,
notify() 的意思是: 從加鎖的對象的監視器(監視器就是鎖)的等待隊列中, 任意取出一個等待線程, 讓該線程處於runnable狀態;
wait()的意思是: 把鎖住對象的當前線程, 放入到監視器的等待隊列中。

所以,notify()的意思就是要喚醒等待隊列中的一個等待線程,當程序發起這么一個事件後, 是由虛擬機的線程調度器完成線程狀態之間的轉換的。

Ⅲ java的等待喚醒機制必須要讓線程等待嗎

1. 線程的掛起和喚醒
掛起實際上是讓線程進入「非可執行」狀態下,在這個狀態下CPU不會分給線程時間片,進入這個狀態可以用來暫停一個線程的運行;在線程掛起後,可以通過重新喚醒線程來使之恢復運行。

掛起的原因可能是如下幾種情況:
(1)通過調用sleep()方法使線程進入休眠狀態,線程在指定時間內不會運行。
(2)通過調用join()方法使線程掛起,使自己等待另一個線程的結果,直到另一個線程執行完畢為止。
(3)通過調用wait()方法使線程掛起,直到線程得到了notify()和notifyAll()消息,線程才會進入「可執行」狀態。
(4)使用suspend掛起線程後,可以通過resume方法喚醒線程。
雖然suspend和resume可以很方便地使線程掛起和喚醒,但由於使用這兩個方法可能會造成死鎖,因此,這兩個方法被標識為deprecated(抗議)標記,這表明在以後的jdk版本中這兩個方法可能被刪除,所以盡量不要使用這兩個方法來操作線程。

調用sleep()、yield()、suspend()的時候並沒有被釋放鎖
調用wait()的時候釋放當前對象的鎖

wait()方法表示,放棄當前對資源的佔有權,一直等到有線程通知,才會運行後面的代碼。
notify()方法表示,當前的線程已經放棄對資源的佔有,通知等待的線程來獲得對資源的佔有權,但是只有一個線程能夠從wait狀態中恢復,然後繼續運行wait()後面的語句。
notifyAll()方法表示,當前的線程已經放棄對資源的佔有,通知所有的等待線程從wait()方法後的語句開始運行。

2.等待和鎖實現資源競爭
等待機制與鎖機制是密切關聯的,對於需要競爭的資源,首先用synchronized確保這段代碼只能一個線程執行,可以再設置一個標志位condition判斷該資源是否准備好,如果沒有,則該線程釋放鎖,自己進入等待狀態,直到接收到notify,程序從wait處繼續向下執行。

synchronized(obj) {
while(!condition) {
obj.wait();
}
obj.doSomething();
}

以上程序表示只有一個線程A獲得了obj鎖後,發現條件condition不滿足,無法繼續下一處理,於是線程A釋放該鎖,進入wait()。

在另一線程B中,如果B更改了某些條件,使得線程A的condition條件滿足了,就可以喚醒線程A:

synchronized(obj) {
condition = true;
obj.notify();
}

需要注意的是:
# 調用obj的wait(), notify()方法前,必須獲得obj鎖,也就是必須寫在synchronized(obj) {...} 代碼段內。
# 調用obj.wait()後,線程A就釋放了obj的鎖,否則線程B無法獲得obj鎖,也就無法在synchronized(obj) {...} 代碼段內喚醒A。
# 當obj.wait()方法返回後,線程A需要再次獲得obj鎖,才能繼續執行。
# 如果A1,A2,A3都在obj.wait(),則B調用obj.notify()只能喚醒A1,A2,A3中的一個(具體哪一個由JVM決定)。
# obj.notifyAll()則能全部喚醒A1,A2,A3,但是要繼續執行obj.wait()的下一條語句,必須獲得obj鎖,因此,A1,A2,A3隻有一個有機會獲得鎖繼續執行,例如A1,其餘的需要等待A1釋放obj鎖之後才能繼續執行。
# 當B調用obj.notify/notifyAll的時候,B正持有obj鎖,因此,A1,A2,A3雖被喚醒,但是仍無法獲得obj鎖。直到B退出synchronized塊,釋放obj鎖後,A1,A2,A3中的一個才有機會獲得鎖繼續執行。

Ⅳ java中如何線程的睡眠與喚醒

classMyThreadextendsThread
{
publicMyThread()
{
super();
}
publicMyThread(Stringname)
{
super(name);
}
publicvoidrun()
{
for(inti=0;i<10;i++)
{
System.out.println(super.getName()+":"+i);
try
{
sleep(500);
}
catch(InterruptedExceptione)
{
System.out.println("線程被叫醒");
}
}
}
}
publicclassSleepTest
{
publicstaticvoidmain(String[]args)
{
MyThreadthread1=newMyThread("第1個線程");
MyThreadthread2=newMyThread("第2個線程");
thread1.start();
thread2.start();
}
}

Ⅳ java線程中怎麼喚醒被wait的線程

notify()方法
無法指定。選擇是任意性的。
喚醒在此對象監視器上等待的單個線程。如果有多個線程都在此對象上等待,則會選擇喚醒其中一個線程。

Ⅵ java 多線程子線程喚醒主線程問題

設一個三個線程的共享對象o
a.start();
b.start();//啟動子線程
主線程中
o.wait(10*1000);//主線程中等10秒
同時A、B中各有一個執行完的通知
a或b的run(){
.....
o.
notify();
}
基本的線程操作...

Ⅶ java如何喚醒指定的等待線程

notify()方法
無法指定。選擇是任意性的。
喚醒在此對象監視器上等待的單個線程。如果有多個線程都在此對象上等待,則會選擇喚醒其中一個線程。

Ⅷ java 怎麼喚醒一個制定的線程呢

當沒有其他線程執行的時候睡眠結束的線程自動運行吧。

Ⅸ java 線程 喚醒等待問題

synchronized(this)
{
notify();
}
所以喚醒的是自己吧?
正確的做法是
thread2
在某個鎖上
wait,另外,在絕大多數情況下都把
notify
換成
notifyAll。因為
notify
一次只喚醒一個,多數情況下我們是根據條件來喚醒的。
Object
lock
=
new
Object();
//
線程2
lock.wait();
//
線程1
lock.notifyAll();

熱點內容
打卡機資料庫 發布:2025-01-11 04:18:36 瀏覽:914
製作產業項目視頻腳本 發布:2025-01-11 04:10:14 瀏覽:185
編程是天賦嗎 發布:2025-01-11 04:10:04 瀏覽:257
軟體編程培訓學院 發布:2025-01-11 04:00:18 瀏覽:846
路虎攬運配置怎麼查詢 發布:2025-01-11 03:42:51 瀏覽:393
仿站源碼 發布:2025-01-11 03:42:05 瀏覽:40
騰訊的雲伺服器 發布:2025-01-11 03:40:47 瀏覽:569
百分之十的演算法 發布:2025-01-11 03:34:30 瀏覽:642
java16進制tostring 發布:2025-01-11 03:24:21 瀏覽:721
mql4c語言 發布:2025-01-11 03:24:20 瀏覽:255