zoukankan      html  css  js  c++  java
  • 多线程的等待唤醒(使用监视器)

    /*
    在jdk1.5版本之后,
    出现了一些新的特性,将原理的线程进行了改良。
    
    在java.util.concurrent.locks包中提供了一个接口Lock。替代了synchronized。
    
    synchronized。使用的是锁操作是隐式的。
    
    Lock接口,使用的锁操作是显示的。
    由两个方法来完成:
    lock():获取锁。
    unlock():释放锁。
    
    
    还有一个对象,Condition.
    该对象的出现替代了Object中的wait notify notifyAll这些操作监视器的方法。
    
    替代后的方式:await  signal  signalAll.
    
    
    
    
    
    接下来,把下列代码替换成JDK1.5版本只有的新对象。
    
    
    
    新功能最大好处,就是在一个Lock锁上,可以添加多组监视器对象。
    
    这样就可以实现本方只唤醒对方的线程
    
    
    
    锁,是同步的机制.通过锁来控制同步.监视器是用于同步中对象的操作.
    比如wait,notify  notifyAll.每一组监视器方法对应一个锁.
    到了jdk1.5以后,将监视器的方式从Object中,封装到了Condition对象中,
    每一个锁lock,可以对应多组监视器对象,这就可以实现本方只唤醒对方的操作。
    
    
    */
    import java.util.concurrent.locks.*;
    class Res
    {
    	private String name;
    	private int count  = 0;
    	private boolean b = false;
    
    	//定义一个锁。
    	Lock lock = new ReentrantLock();
    
    	//通过指定的锁,创建了一个该锁上可以使用了监视器对象。
    	Condition proCon = lock.newCondition();
    
    	//升级后的lock可以对应多组监视器对象。
    	Condition cusCon = lock.newCondition();
    
    
    	public void set(String name)
    	{
    		//获取锁。
    		lock.lock();
    		try
    		{	
    			while(b)
    				proCon.await();
    			this.name = name+"--------"+count;
    			count++;
    			System.out.println(Thread.currentThread().getName()+".....生产者...."+this.name);
    			b = true;
    			cusCon.signal();
    		}
    		catch(InterruptedException e)
    		{
    		
    		}
    		finally
    		{
    			//释放锁
    			lock.unlock();
    		}
    
    
    	}
    
    
    	public void out()
    	{
    		lock.lock();
    		try
    		{
    			while(!b)
    				cusCon.await();
    			System.out.println(Thread.currentThread().getName()+"----消费者---"+this.name);
    			b = false;
    			proCon.signal();
    
    		}
    		catch (InterruptedException e)
    		{
    		}
    		finally
    		{
    			lock.unlock();
    		}
    	}
    	
    }
    
    
    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 ProCusDemo2 
    {
    	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,t4都是消费者。
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    	}
    }
    

      

  • 相关阅读:
    232. Implement Queue using Stacks
    231. Power of Two
    n&(n-1)位运算的妙用
    230. Kth Smallest Element in a BST
    关于UNIX的exec函数
    Go语言的各种Print函数
    Go语言的接口interface、struct和组合、继承
    Go语言知识点笔记
    Ubuntu自定义终端窗口位置
    Python的类变量和成员变量、类静态方法和类成员方法
  • 原文地址:https://www.cnblogs.com/liushisaonian/p/8595376.html
Copyright © 2011-2022 走看看