多執行緒&定時器Timer&同步&執行緒通訊&ThreadLocal
阿新 • • 發佈:2018-11-25
1.多執行緒
- 執行緒狀態分為:新建狀態、就緒狀態、執行狀態、阻塞狀態、死亡狀態
- 物件等待池的阻塞狀態:執行狀態執行了wait方法
- 對向鎖池的阻塞狀態:試圖獲得某個同步鎖,已經被其他執行緒佔用,就會放到物件的鎖池中
- 其他阻塞狀態:執行了sleep()方法、join方法()
- 執行緒睡眠Thread.sleep()方法:當前執行緒放棄cpu,轉到阻塞狀態
- 執行緒讓步Thead.yield()靜態方法:如果此時具有相同優先順序的其他執行緒處於就緒狀態,那麼 yield()方法將把當前執行的執行緒放到可執行池中並使另一個執行緒執行。如果沒有相同優先順序的可執行執行緒,則此方法什麼都不做。
- 等待其他執行緒結束 join()方法:當前執行的執行緒可以呼叫另一個執行緒的 join()方法,當前執行的執行緒將轉到阻塞狀態,直至另一個執行緒執行結束,它才恢復執行。
- machin.join() 就是執行的這個執行緒停止讓給machin執行緒執行
- 設定後臺執行緒 Thread.setaemon(true)方法,就可以把當前執行緒設定為後臺執行緒
2.定時器Timer
Timer timer = new Timer(true) //把與Timer關聯的執行緒設定為後臺執行緒
TimerTask task = new TimerTask(){//匿名內部類實現run方法
timer.schedule(task,10,500); //task用來設定所要定時器執行的任務;10為延遲執行的時間ms;500為每隔500ms重複執行一次任務
}
3.同步
- 同步程式碼塊
- synchronized(this){} this表示引用當前類物件的鎖
- 同步方法鎖
- public synchronized String pop(){}
- 什麼情況會釋放鎖?
執行完同步程式碼塊,就會釋放鎖- 在執行同步程式碼塊的過程中,遇到異常而導致執行緒終止,鎖也會被釋放
- 在執行同步程式碼塊的過程中,執行了鎖所屬物件的wait()方法,這個執行緒會釋放鎖,進入物件的等待池
- 什麼情況不會釋放鎖?
- 在執行同步程式碼塊的過程中,執行了 Thread.sleep()方法,當前執行緒放棄 CPU,開始睡眠,在睡眠中不會釋放鎖
- 在執行同步程式碼塊的過程中,執行了 Thread.yield()方法,當前執行緒放棄 CPU,但不會釋放鎖
- 在執行同步程式碼塊的過程中,其他執行緒執行了當前執行緒物件的 supend()發昂發,當前執行緒被暫停,但不會釋放鎖。Thread類的 supend()方法已經被廢棄
4.執行緒通訊
- wait():執行該方法的執行緒釋放物件的鎖,Java虛擬機器把該執行緒放到該物件的等待池中。該執行緒等待其他執行緒將它喚醒
- notify():執行該方法的執行緒喚醒在物件的等待池中等待的一個執行緒。Java虛擬機器從物件等待池中隨機選擇一個執行緒,把它轉到物件的鎖池中
- notifyAll():喚醒所有在等待池中的執行緒。
5.中斷阻塞
當執行緒 A 處於阻塞狀態時, 如果執行緒 B 呼叫執行緒 A 的 interrupt()方法,那麼執行緒 A 會接收到一個 InterruptedException,並退出阻塞狀態,開始進行異常處理
6.執行緒控制
- start():啟動執行緒
- suspend():使執行緒暫停(被廢棄)
- resume():使暫停的執行緒恢復執行(被廢棄)
- stop()::終止執行緒(被廢棄)
7.執行緒組
ThreadGroup類的 activeCount()方法:獲得當前或者的執行緒的數目
ThreadGroup類的 enumerate(machines)方法:該方法把當前活著的執行緒引用存放到引數machines中
main(){
ThreadGroup group = new ThreadGroup("machines");
for(int i = 1;i <= 5;i++){
Machine machine = new Machine(group,"machine"+i);
machine.start();
}
int activeCount = group.activeCount();
Thread[] machines = new Thread[activeCount];
group.enumerate(machines);
for(int i = 0;i < activeCount;i++)
syso(machines[i].getName()+" is alive");
}
8.ThreadLocal
- ThreadLocal類 可以用來存放執行緒的區域性變數,每個執行緒都有單獨的區域性變數,彼此之間不會共享
- public T get():返回當前執行緒的區域性變數
- protected T initialValue():返回當前執行緒的區域性變數的初始值
- public void set(T value):設定當前執行緒的區域性變數
- ThreadLocal類中有一個Map 快取,使用者儲存每一個執行緒的區域性變數