多线程-juc-lock实现精准唤醒

用juc包里lock+await+signal的组合替换传统的synchronized+wait+notify,以实现精准通知,精准唤醒

场景:

有三种线程A,B,C,让它们轮流打印:A打印5遍“我是A”,B打印10遍“我是B”,C打印15遍“我是C”,A打印5遍“我是A”…这样交替打印。
现假设A,B,C各有10个线程

代码:
/**
 * 
 * @ClassName: Printer
 * @Description: 打印机资源类
 * @author: fuling
 * @date: 2020年9月10日 下午12:37:39
 */
class Printer{
	private int flag = 1; //标志位,表示当前应该轮到哪种线程打印
	private Lock lock = new ReentrantLock(); //一把资源锁
	private Condition condition1 = lock.newCondition(); //A类线程拥有的资源锁钥匙1
	private Condition condition2 = lock.newCondition(); //B类线程拥有的资源锁钥匙2
	private Condition condition3 = lock.newCondition(); //C类线程拥有的资源锁钥匙3
	
	/**
	 * 
	 * @Title: printA
	 * @Description: A类线程的打印操作
	 * @return: void
	 */
	public void printA() {
		lock.lock();
		try {
			//判断是否轮到A线程打印
			while(this.flag != 1) {
				condition1.await();
			}
			
			//A线程开始打印
			for(int i = 0; i < 5; i++) {
				System.out.println("我是A线程");
			}
			
			//A线程打印完毕,标识位置为2,唤醒B种类的线程
			this.flag = 2;
			condition2.signalAll();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			lock.unlock();
		}
		
		
	}
	
	/**
	 * 
	 * @Title: printB
	 * @Description: B类线程的打印操作
	 * @return: void
	 */
	public void printB() {
		lock.lock();
		try {
			//判断是否轮到B线程打印
			while(this.flag != 2) {
				condition2.await();
			}
			
			//B线程开始打印
			for(int i = 0; i < 10; i++) {
				System.out.println("我是B线程");
			}
			
			//B线程打印完毕,标识位置为3,唤醒C种类的线程
			this.flag = 3;
			condition3.signalAll();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			lock.unlock();
		}
		
		
	}
	
	/**
	 * 
	 * @Title: printC
	 * @Description: C类线程的打印操作
	 * @return: void
	 */
	public void printC() {
		lock.lock();
		try {
			//判断是否轮到C线程打印
			while(this.flag != 3) {
				condition3.await();
			}
			
			//C线程开始打印
			for(int i = 0; i < 15; i++) {
				System.out.println("我是C线程");
			}
			
			//C线程打印完毕,标识位置为1,唤醒A种类的线程
			this.flag = 1;
			condition1.signalAll();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			lock.unlock();
		}
		
		
	}
}


/**
 * 
 * @ClassName: LockDemo2
 * @Description: 启动类,测试闭环调用
 * @author: fuling
 * @date: 2020年9月10日 下午12:51:06
 */
public class LockDemo2 {
	public static void main(String[] args) {
		Printer printer = new Printer();//获取打印机资源类
		
		//创建A,B,C线程各10个
		for(int i = 0; i < 10; i++) {
			new Thread(()->{
				printer.printA();
			}).start();;
		}
		
		for(int i = 0; i < 10; i++) {
			new Thread(()->{
				printer.printB();
			}).start();;
		}
		
		for(int i = 0; i < 10; i++) {
			new Thread(()->{
				printer.printC();
			}).start();;
		}
		
	}
}
执行结果

我是A线程
我是A线程
我是A线程
我是A线程
我是A线程
我是B线程
我是B线程
我是B线程
我是B线程
我是B线程
我是B线程
我是B线程
我是B线程
我是B线程
我是B线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是C线程
我是A线程
我是A线程
我是A线程
我是A线程
我是A线程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值