Java多线程技术初识——9,等待唤醒机制(二)

这篇主要讲解,JDK1.5以后,对多线程技术的改进。那么,为什么要对之前的技术进行改进呢,在上篇中的多生产者,多消费者例子中,当有一个线程在执行时,其他的线程在申请对锁的拥有权是,会不断的进行判断,这样会降低降低程序的性能。为此,JDK 1.5 以后,对多线程技术做了改进。

JDK1.5后出现的新的接口和类:Lock:比同步函数和同步代码块要好一些。同步函数还是同步代码块所做的都是隐式的锁操作。并且,同步函数或者同步代码块使用的锁和监视器是同一个。

Lock接口:是将锁进行单独对象的封装。而且提供了对锁对象很多功能。  比如:lock()获取锁,unlock()释放锁。  Lock对锁的操作都是显示操作。所以它的出现要比同步函数或者同步代码块明确的多,更符合面向对象思想。

简单一句话:Lock接口的出现替代同步。

下面将上述的生产者消费者 代码,进行 Lock 改写:

class Resource
{

	private String name;
	private int count = 1;
	private boolean flag;
	//创建一个锁对象。
	private final Lock lock = new ReentrantLock();
	//获取一个该锁上的监视器。 
	private Condition con = lock.newCondition();
	public  void set(String name)//  
	{
		//获取锁。
		lock.lock();
		try
		{
		
			while(flag)
				try{con.await();}catch(InterruptedException e){}
			this.name = name + count; 

			count++;
			System.out.println(Thread.currentThread().getName()+".....生产者......"+this.name);
																							
			flag = true;
			con.signalAll();
		}
		finally
		{
			//释放锁。
			lock.unlock();
		}
	}

	public  void get()//  
	{
		lock.lock();
		try
		{
			
		
			while(!flag)
				try{con.await();}catch(InterruptedException e){}

			System.out.println(Thread.currentThread().getName()+".........消费者......"+this.name);
			flag = false;
			con.signalAll();
		}
		finally
		{
			lock.unlock();
		}
	}
}
这样,对锁的操作显而易见。清晰的很。

原来在同步中,锁和监视器是同一个对象。现在,升级后,锁是一个单独的对象。而且将监视器的方法也单独封装到了一个对象中。这个对象就是升级后Condition.

升级后,都进行了单独的封装。锁被封装成了Lock对象。监视器方法都被封装到了Condition对象(监视器对象)中。 说白了,Lock替代了同步,Condition替代了Object中的监视器方法。

Condition中提供了监视器的方法:awati().signal(),signalAll();

那么,该 如何让锁和监视器产生联系呢?

  直接通过Lock接口中的newCondition()方法就可以获取到能绑定到该Lock对象的上的监视器对象Condition。

之前,我们为了解决,1,本方唤醒了本方。2,被唤醒的本方没有判断标记。这两个问题时,将if 改为  while , 并且用了 notifyAll() ,这种解决方案效率低,因为还会唤醒本方。

 有了新特性Lock,Condition。就可以解决这个问题了。之前是有两个锁嵌套,容易死锁,现在方案是只有锁,但是锁上可以加入多个监视器 :一个监视生产者,一个监视消费者。

改写后的代码为:

class Resource
{

	private String name;
	private int count = 1;
	private boolean flag;
	//创建一个锁对象。
	private final Lock lock = new ReentrantLock();
	//创建一个生产者的监视器。
	private Condition producer_con = lock.newCondition();
	//创建一个消费者监视器。
	private Condition consumer_con = lock.newCondition();
	
	public  void set(String name)//  
	{
		//获取锁。
		lock.lock();
		try
		{
		
			while(flag)
				try{producer_con.await();}catch(InterruptedException e){}
			this.name = name + count;

			count++;

			System.out.println(Thread.currentThread().getName()+".....生产者......"+this.name);																							
			flag = true;
			consumer_con.signal();
		}
		finally
		{
			//释放锁。
			lock.unlock();
		}
	}

	public  void get()//  
	{
		lock.lock();
		try
		{
					
			while(!flag)
				try{consumer_con.await();}catch(InterruptedException e){}

			System.out.println(Thread.currentThread().getName()+".........消费者......"+this.name);
			flag = false;
			producer_con.signal();
		}
		finally
		{
			lock.unlock();
		}
	}
}


返回主目录




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值