1. 程式人生 > >多執行緒&定時器Timer&同步&執行緒通訊&ThreadLocal

多執行緒&定時器Timer&同步&執行緒通訊&ThreadLocal

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 快取,使用者儲存每一個執行緒的區域性變數