JAVA中wait和notify,sleep

本文详细解析了Java多线程中Wait与Notify的工作原理及使用注意事项,包括它们在同步块中的作用、与NotifyAll的区别,以及如何避免死锁等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在java多线程中需要用到wait和notify。

这两个操作都必须在同步块内部。

调用wait之后就会在wait位置上卡住,把当前同步的锁释放,从新等待当前对象的锁。

当notify的时候,首先将同步块运行结束,然后释放锁并通知其他wait线程开始进行锁竞争。其他wait线程只有一个可以获得锁。

那notify和notifyAll有什么区别呢?notify是唤醒多个wait线程中的一个并让他继续工作,notifyAll是唤醒所有的wait线程让他们重新进行锁的竞争。使用notify和notifyall的时候需要注意,notify与wait必须是一对一的,需要写程序的时候控制好,避免有wait无notify的情况。使用notifyall的时候是让所有的wait线程有机会(其中一个获取锁,其他的也都获取锁的时候也会继续)向下执行,就需要考虑wait方法后续的资源是否可以使用的情况。

sleep是Thread的静态方法,他不是多线程用的,好多人把他与多线程联系是不正确的。

sleep是使得当前线程卡主等待,跟锁或者同步有关系。

从应用上讲,wait和sleep都是使得线程卡主,都可以通过interrupt打断。

 

JAVA多线程造成死锁的可能有:

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

转载于:https://my.oschina.net/u/1458864/blog/284570

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值