欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java多线程详记(四)——wait,nitify用法(生产者消费者问题)

程序员文章站 2024-03-24 13:47:22
...

wait()、notify()是Object提供的两个非常重要的方法,也就是说所有的对象都可已使用这两个方法,那么这两个方法怎么使用呢,其能够解决的消费者生产者问题又是在什么样的应用场景下呢?
在代码中,当在一个实例对象调用wait方法,那么当前线程就会从执行状态转变成等待状态,同时释放在实例对象上的锁,直到其它线程在刚才那个实例对象上调用notify方法并且释放实例对象上的锁,那么刚才那个当前线程才会再次获取实例对象锁并且继续执行。这样我们通过object对象就可以让多线程之间进行有效通信
读了上面一段话,你是否能够想象出这两个方法到底应该应用在什么场景下呢?

由于我们需要用同一对象唤醒、等待,所以一般来说,我们会将这两个方法应用在多线程调用、执行的“资源”里面,这样使用this关键字等待、唤醒会方便的多。

wait()、notify()能够解决生产者消费者的“顺序执行问题”(生产者生产后,消费者才能拿去消费),那么怎么样避免生产者、消费者,同时使用同一资源的问题呢(我生产者还没生产出来,你就拿去消费,肯定不现实的嘛),者就需要使用上一篇讲到的sychronized关键字用法了,把资源锁住,我搞完了你再去消费、生产。
代码实现:

class Resource{  //生产者和消费者都要操作的资源  
   private String name;  
   private int count=1;  
   private boolean flag=false;  
   public synchronized void set(String name){  
       if(flag) {
    	   try{
    		   wait();
    	   }catch(Exception e){}
       }             
       this.name=name+"---"+count++;  
       System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);  
       flag=true;  
       this.notify();  
   }  
   public synchronized void out(){  
       if(!flag) {
    	   try{
    		   wait();
    	   }catch(Exception e){};
       }         
       System.out.println(Thread.currentThread().getName()+"...消费者..."+this.name);  
       flag=false;  
       this.notify();  
   }  
}  
class Producer implements Runnable{  
   private Resource res;  
   Producer(Resource res){  
       this.res=res;  
   }  
   public void run(){  
       while(true){ 
    	   try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
           res.set("商品");  
       }  
   }  
}  
class Consumer implements Runnable{  
   private Resource res;  
   Consumer(Resource res){  
       this.res=res;  
   }  
   public void run(){  
       while(true){  
    	   try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
           res.out();  
       }  
   }  
}  
public class ThreadCommunicate{  
   public static void main(String[] args){  
       Resource r=new Resource();  
       Producer pro=new Producer(r);  
       Consumer con=new Consumer(r);  
       Thread t1=new Thread(pro);  
       Thread t2=new Thread(con);  
       t1.start();  
       t2.start();  
   }  
}

Java多线程详记(四)——wait,nitify用法(生产者消费者问题)
运行结果正常,生产者生产一个商品,紧接着消费者消费一个商品。


wait和sleep的区别

1、sleep是线程中的方法,但是wait是Object中的方法。

2、sleep方法不会释放锁,但是wait会释放,而且会加入到等待队列中。

3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。

4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。

记得点赞加关注哦!!