JAVA中wait和notify,sleep

在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

  1. 對於一把鎖,wait以後忘記notify同步

  2. 對於多把鎖,當線程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();
//   }
  }
 }
}
相關文章
相關標籤/搜索