多執行緒控制線程的等待和喚醒

2022-07-15 04:54:11 字數 3146 閱讀 3975

最近做註冊的時候,發現同步傳送註冊郵件多了乙個耗時,就想到非同步處理郵件傳送,直接返回成功給使用者。

設計了乙個執行緒,用來傳送郵件,需要傳送的時候再來喚醒就好了,但是對於沒有系統了解過多執行緒的我來說,想的太簡單了。

public

class mailsendthread extends

thread

catch

(exception e)

}}

private

static mailsendthread mailsender = new

mailsendthread();

public

static

void

notifymailsender()

多傻的**!!!!

仔細研究後發現,首先sleep只能用作執行緒內部等待使用,指定時間段內休眠,不能外部喚醒;

其次,nofity方法必須依託與乙個執行緒正在等待的物件,就是鎖住的物件,不能直接對執行緒操作,因為wait函式需要乙個鎖;

研究了一下生產者和消費者,這裡用到的鎖是物件例項

package

com.thread;

/*** 生產者,製造饅頭

* @author

huangjc *

*/public

class a extends

thread

public

void

run()

catch

(interruptedexception e) }}

}

package

com.thread;

/*** 消費者,消耗饅頭

* @author

huangjc *

*/public

class b extends

thread

public

void

run()

}public

static

void

main(string args)

}

具體的鎖就在下面

package

com.thread;

public

class

c else

}public

synchronized

void

minus()

catch

(interruptedexception e)

}else

}}

這裡的notify和wait方法鎖住的都是在b的main方法中建立的例項物件

所以問題又來了,我需要在主線程中啟動分執行緒,所以不能給兩個執行緒分配同乙個例項物件,如果每次都重新分配乙個例項物件,再建立乙個分執行緒,是不是太愚蠢了;

對於靜態方法和非靜態方法的同步問題,靜態方法鎖住的是class,例如a.class,而非靜態方法鎖住的是當前例項。

所以靜態方法和非靜態方法並不適用同乙個鎖。乙個類中的所有靜態方法使用同乙個鎖。

所以,是否可以考慮使用靜態方法來傳送郵件,鎖住類本身,然後再主線程中依託類本身進行喚醒;

太坑爹了,完全不是這回事,查了api後發現,wait方法是object物件的,那不就是說必須依託於乙個物件例項嗎?

再來看api中關於thread類下面的方法,其中有個

interrupt()
interrupt

public

void

interrupt()

中斷執行緒。

如果當前執行緒沒有中斷它自己(這在任何情況下都是允許的),則該執行緒的 checkaccess 方法就會被呼叫,這可能丟擲 securityexception。

如果執行緒在呼叫 object 類的 wait()、wait(

long) 或 wait(long, int) 方法,或者該類的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int

) 方法過程中受阻,則其中斷狀態將被清除,它還將收到乙個 interruptedexception。

如果該執行緒在可中斷的通道上的 i/o 操作中受阻,則該通道將被關閉,該執行緒的中斷狀態將被設定並且該執行緒將收到乙個 closedbyinterruptexception。

如果該執行緒在乙個 selector 中受阻,則該執行緒的中斷狀態將被設定,它將立即從選擇操作返回,並可能帶有乙個非零值,就好像呼叫了選擇器的 wakeup 方法一樣。

如果以前的條件都沒有儲存,則該執行緒的中斷狀態將被設定。

中斷乙個不處於活動狀態的執行緒不需要任何作用。

丟擲:securityexception - 如果當前執行緒無法修改該執行緒

執行緒a正在使用sleep()暫停著: thread.sleep(100000);

如果要取消他的等待狀態,可以在正在執行的執行緒裡(比如這裡是b)呼叫

a.interrupt();

令執行緒a放棄睡眠操作,這裡a是執行緒a對應到的thread例項

執行interrupt()時,並不需要獲取thread例項的鎖定.任何執行緒在任何時刻,都可以呼叫其他執行緒interrupt().當sleep中的執行緒被呼叫interrupt()時,就會放棄暫停的狀態.並丟擲interruptedexception.丟出異常的,是a執行緒

package

com.thread;

/*** 消費者,消耗饅頭

* @author

huangjc *

*/public

class b extends

thread

catch

(interruptedexception e) }}

public

static

void

main(string args)

system.out.println("別睡了");

b.interrupt();

}}

執行main函式

執行緒執行

睡一會兒

別睡了cao ,誰在打擾我睡覺呢!

執行緒執行

睡一會兒

執行緒控制(執行緒同步 執行緒安全)

一 執行緒同步 當多個控制線程共享相同的記憶體時,需要確保每個執行緒看到一致的資料。如果當某個執行緒可以去修改變數,而其他執行緒也可以去讀取或者修改這個變數的時候,就需要對這些執行緒進行同步控制,以確保它們在訪問變數的儲存內容時不會訪問到無效的數值。同步 多程序或者多執行緒訪問臨界資源時,必須進行同...

Linux 執行緒控制 執行緒建立

作業系統並沒有提供執行緒控制的相關介面,大佬分裝了一套執行緒控制介面。執行緒裡我們用庫函式,所以說這套介面建立的執行緒是使用者態執行緒,並且這個使用者態執行緒在作業系統中對應了乙個輕量級程序。功能 建立 個新的執行緒 原型 int pthread create pthread t thread,co...

java 多執行緒 等待喚醒機制

package thread執行緒 生產者消費者問題 問題1 為什麼要用while而不用if進行判斷 因為是多執行緒在操作同一資源,即有多個生產者也有多個消費者,如果用if進行判斷的話會出現生產者生產連續生產多次,而消費者只消費 消費一次,或生產者生產一次消費者消費多次的錯誤資訊,這是為什麼呢?原因...