在java多線程中須要用到wait和notify。java
這兩個操做都必須在同步塊內部。多線程
調用wait以後就會在wait位置上卡住,把當前同步的鎖釋放,重新等待當前對象的鎖。this
當notify的時候,首先將同步塊運行結束,而後釋放鎖並通知其餘wait線程開始進行鎖競爭。其餘wait線程只有一個能夠得到鎖。線程
那notify和notifyAll有什麼區別呢?notify是喚醒多個wait線程中的一個並讓他繼續工做,notifyAll是喚醒全部的wait線程讓他們從新進行鎖的競爭。使用notify和notifyall的時候須要注意,notify與wait必須是一對一的,須要寫程序的時候控制好,避免有wait無notify的狀況。使用notifyall的時候是讓全部的wait線程有機會(其中一個獲取鎖,其餘的也都獲取鎖的時候也會繼續)向下執行,就須要考慮wait方法後續的資源是否可使用的狀況。code
sleep是Thread的靜態方法,他不是多線程用的,好多人把他與多線程聯繫是不正確的。對象
sleep是使得當前線程卡主等待,跟鎖或者同步有關係。資源
從應用上講,wait和sleep都是使得線程卡主,均可以經過interrupt打斷。rem
JAVA多線程形成死鎖的可能有:get
對於一把鎖,wait以後忘記notify同步
對於多把鎖,當線程1拿到了A鎖,線程2拿到了B鎖,這是線程1等待B鎖,線程2等待A鎖
package spyudemo.thread; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import javax.management.Query; public class TestQueue { public LinkedList queueList=new LinkedList(); private SendThread[] sendThreadArr=null; public TestQueue(int threadNum){ sendThreadArr=new SendThread[threadNum]; for(int i=0;i<threadNum;i++){ sendThreadArr[i]=new SendThread("thread:"+i+" "); sendThreadArr[i].start(); } } public void addInfo(Object objcet){ synchronized (queueList) { queueList.add(objcet); queueList.notifyAll(); } } public class SendThread extends Thread{ public SendThread(String name){ this.setName(name); } public void run(){ while(true){ synchronized (queueList) { System.out.println(this.getName()+"11111111"); if(queueList.isEmpty()){ try { System.out.println(this.getName()+"22222222222"); queueList.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //使用notifyALl在這裏須要判斷是否爲空 //使用notify因爲是一對一的,這裏能夠不作判斷 if(!queueList.isEmpty()){ Object obj=queueList.removeFirst(); System.out.println(this.getName()+"33333333333333333333"); } } } } } public static void main(String[] args){ TestQueue test=new TestQueue(10); for(int i=0;i<10;i++){ test.addInfo(new Object()); // try { // Thread.sleep(2000); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } } } }