最近做註冊的時候,發現同步傳送註冊郵件多了乙個耗時,就想到非同步處理郵件傳送,直接返回成功給使用者。
設計了乙個執行緒,用來傳送郵件,需要傳送的時候再來喚醒就好了,但是對於沒有系統了解過多執行緒的我來說,想的太簡單了。
publicclass mailsendthread extends
thread
catch
(exception e)
}}
privatestatic mailsendthread mailsender = new
mailsendthread();
public
static
void
notifymailsender()
多傻的**!!!!
仔細研究後發現,首先sleep只能用作執行緒內部等待使用,指定時間段內休眠,不能外部喚醒;
其次,nofity方法必須依託與乙個執行緒正在等待的物件,就是鎖住的物件,不能直接對執行緒操作,因為wait函式需要乙個鎖;
研究了一下生產者和消費者,這裡用到的鎖是物件例項
packagecom.thread;
/*** 生產者,製造饅頭
* @author
huangjc *
*/public
class a extends
thread
public
void
run()
catch
(interruptedexception e) }}
}
packagecom.thread;
/*** 消費者,消耗饅頭
* @author
huangjc *
*/public
class b extends
thread
public
void
run()
}public
static
void
main(string args)
}
具體的鎖就在下面
packagecom.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()
interruptpublic
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執行緒
packagecom.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進行判斷的話會出現生產者生產連續生產多次,而消費者只消費 消費一次,或生產者生產一次消費者消費多次的錯誤資訊,這是為什麼呢?原因...