Java多线程 10 处理锁的更好选择

相对与从前苦逼的同步机制,Java 5 出现了更优化更直观的 Lock 和 Condition 两个新机制可以用,并且一个 Lock 可以对应多个 Condition,从而允许不一样的等待和唤醒机制。

package thread;

import java.util.concurrent.locks.*;

/*
该对象可以Lock锁 进行获取。该示例中,实现了本方只唤醒对方操作。

JDK1.5 中提供了多线程升级解决方案。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notify notifyAll,替换成Condition对象。

Lock类的官方解释:
    实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。
    此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。

Condition的官方解释:
    将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,
    以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。
    
    其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。

Lock:替代了Synchronized
	lock 
	unlock
	newCondition()

Condition:替代了Object 的 wait notify notifyAll
	await();
	signal();
	signalAll();
*/

public class Thread_6_ProducerConsumerDemo3 {
	public static void main(String[] args) 
	{
		Resource2 r = new Resource2();

		Producer2 pro = new Producer2(r);
		Consumer2 con = new Consumer2(r);

		Thread t1 = new Thread(pro);
		Thread t2 = new Thread(pro);
		Thread t3 = new Thread(con);
		Thread t4 = new Thread(con);

		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

class Resource2{
	private String name;
	private int count = 1;
	private boolean flag = false;
	
	//建立一个锁,舍弃了之前直接拿res对象做锁的方法
	//相对与从前的将某个对象或类视作“锁”的策略
	//Lock类直接将“锁”这个概念明朗化了
	private Lock lock = new ReentrantLock();	
	
	//同一个lock上可以由多个相关的condition
	//被A condition叫去wait的线程,只能由A conditon唤醒
	//避免了同步块嵌套导致死锁的危险
	private Condition AAAAAA = lock.newCondition();
	private Condition BBBBBB = lock.newCondition();
	
	public void set(String name)
	{
		lock.lock();	//同步块开始
		
		try{
			while(flag)
				AAAAAA.await();	//如果仓库已满,生产者被 A 叫去等待
				
			this.name = name+"--"+count++;
			System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
			flag = true;
			
			//生产完毕,所有消费者被 B 唤醒
			BBBBBB.signalAll();	
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//finally块里面一般放的都是释放资源的动作
			//同步块结束,释放锁的动作必须执行
			lock.unlock();	
		}
	}

	public void out()
	
	{
		lock.lock();	//同步块开始
		try{
			while(!flag)
				BBBBBB.await();		//如果仓库已空,消费者被 B 叫去等待
			
			System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
			flag = false;
			
			AAAAAA.signalAll();		//
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			lock.unlock();	//同步块结束
		}
	}
}

class Producer2 implements Runnable{
	private Resource2 res;

	Producer2(Resource2 res){
		this.res = res;
	}
	
	public void run(){
		while(true)	{
			res.set("+商品+");
		}
	}
}

class Consumer2 implements Runnable{
	private Resource2 res;

	Consumer2(Resource2 r){
		this.res = r;
	}
	
	public void run(){
		while(true){
			res.out();
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值