在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(); // } } } }