zoukankan      html  css  js  c++  java
  • 多线程的等待唤醒机制

    一般的的等待和唤醒机制

    /*
     生产者,消费者。
    
    
    代码完成,加入同步和等待唤醒机制后,可以实现,生产一个,就消费一个。
    
    可是在实际开发中,生产者和消费者,不是一个。有可能是多个
    也就是有多个生产者生产,有多个消费者消费。
    
    
    造成数据错误的原因:当生产者消费者多个时,
    本方的线程有可能唤醒本方的线程,而且,本方被唤醒后,没有判断标记,就进行了执行,
    会到导致原来本方的操作还没有被对方所操作就已经被覆盖了。
    
    生产者1,进行了生产后,将本方生产者2唤醒,生产者2没有判断标记直接继续生产,
    导致生产者1的产品还没有被消费就覆盖了。
    
    解决方式:因为有本方唤醒本方的情况,所以必须每次的醒来都要判断一次标记。
    
    判断标记的动作要执行多次。所以不使用if,而是使用while.
    
    
    当进行while标记判断后,本方唤醒本方的动作还会发生,但是本方被唤醒后,继续判断标记,
    虽然没有将前一次操作覆盖,但是导致了程序中的线程都处于了等待状态。
    导致程序处于死锁状态。
    
    
    
    到这里,发现,原因,有两个:
    1,是判断标记。通过循环判断比较搞定。
    2,一定要唤醒对方。notify是唤醒一个,这个线程有可能是本方,也有可能是对方。
    	干脆,无论是本方还是对方,全唤醒。通过notifyAll搞定。
    
    
    */
    class Res
    {
    	private String name;
    	private int count  = 0;
    	private boolean b = false;
    	public synchronized void set(String name)
    	{
    		while(b)
    			try{this.wait();}catch(Exception e){}
    												
    		this.name = name+"----"+count;
    
    		count++;
    
    		System.out.println(Thread.currentThread().getName()+".....生产者...."+this.name);
    
    		b = true;
    		this.notifyAll(); 
    	}
    
    	public synchronized void out()
    	{
    		while(!b)
    			try{this.wait();}catch(Exception e){}
    		System.out.println(Thread.currentThread().getName()+"----消费者---"+this.name);
    		b = false;
    		this.notifyAll();
    	}
    }
    
    
    class Pro implements Runnable
    {
    	private Res r;
    	Pro(Res r)
    	{
    		this.r = r;
    	}
    	public void run()
    	{
    		while(true)
    		{
    			r.set("产品");
    		}
    	}
    }
    class Cus implements Runnable
    {
    	private Res r;
    	Cus(Res r)
    	{
    		this.r = r;
    	}
    	public void run()
    	{
    		while(true)
    		{
    			r.out();
    		}
    	}
    }
    
    
    
    class ProCusDemo 
    {
    	public static void main(String[] args) 
    	{
    		Res r = new Res();
    		Pro p = new Pro(r);
    		Cus c = new Cus(r);
    
    		Thread t1 = new Thread(p);
    		Thread t2 = new Thread(p);
    		Thread t3 = new Thread(c);
    		Thread t4 = new Thread(c);
    		//t1,t2都是生产者。
    		//t3,t3都是消费者。
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    	}
    }
    

      

  • 相关阅读:
    死锁
    钩子函数和回调函数的区别
    蓝绿部署、滚动发布、灰度发布的介绍以及最佳实践
    小公司的瓶颈
    Modbus协议详解
    windows+jenkin
    Java:简单的多态实例
    一、Kubernetes系列之介绍篇
    Shell脚本自动搭建ipsec环境
    Appium(1):安卓自动化环境搭建 + Android SDK + Appium 环境搭建
  • 原文地址:https://www.cnblogs.com/liushisaonian/p/8598345.html
Copyright © 2011-2022 走看看