多线程进阶之并发工具类第一篇:CountDownLatch、CyclicBarrier

在java.util.concurrent包下有4个非常有用的并发工具类。CountDownLatch、CyclicBarrier提供了一种并发流程控制的手段。

1.CountDownLatch探究:

主要用到其两个实例方法:countDown()和await(),这两个方法配合使用,效果等同于Thread实例的join方法:

案例:有两个子线程,让这两个子线程执行完之后再执行主线程。

使用join:

public static void main(String[] args) {
	Thread thread1 = new Thread(new Runnable() {
		public void run() {
			System.out.println(Thread.currentThread().getName() + "执行");
		}
	}, "线程1");

	Thread thread2 = new Thread(new Runnable() {
		public void run() {
			System.out.println(Thread.currentThread().getName() + "执行");
		}
	}, "线程2");
	thread1.start();
	thread2.start();
	try {
		thread1.join();
		thread2.join();
	} catch (Exception e) {
		e.printStackTrace();
	}
	System.out.println(Thread.currentThread().getName() + "执行");
}
使用CountDownLatch工具类:

public class DownCountLatchTest {
	static CountDownLatch c = new CountDownLatch(2);

	public static void main(String[] args) {
		new Thread(new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName() + "执行结束");
				c.countDown();
			}
		}, "线程1").start();

		new Thread(new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName() + "执行结束");
				c.countDown();
			}
		}, "线程2").start();

		try {
			c.await();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "执行");
	}
}
以上,先创建CountDownLatch实例,只有一个构造器CountDownLatch(int count),需要传入一个正整数,这个正整数就代表计数器。在主线程中调用了CountDownLatch实例的await()方法,代表主线程阻塞,只有等计数器变为0的时候才会解除阻塞。而在每个子线程中都调用了CountDownLatch实例的countDown()方法,每调用一次CountDownLatch实例的countDown()方法,CountDownLatch实例的计数器就会减1,如果能减到0,则主线程解除阻塞,如果减不到0(比如一开始计数器是3,而两个子线程各自只调用了一次CountDownLatch实例的countDown()方法),则主线程会一直阻塞,所以在一开始创建CountDownLatch的实例时要设计好到底要传多大的数进去。

2.CyclicBarrier探究:

CyclicBarrier字面意思是可循环使用的屏障。它的作用是让一组线程到达一个屏障时被阻塞,直到指定数量的线程到达屏障时,屏障才会打开,所有被屏障拦截的线程才会继续往下执行。

public class CyclicBarrierTest {

	static CyclicBarrier c = new CyclicBarrier(2);

	public static void main(String[] args) {
		new Thread(new Runnable() {
			public void run() {
				try {
					c.await();
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + "执行");
			}
		}, "线程1").start();

		try {
			c.await();
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println(Thread.currentThread().getName() + "执行");

	}
}
以上,先用CyclicBarrier(int parties)构造器创建了一个会阻塞2个线程的CyclicBarrier实例。在子线程中和主线程中都调用了CyclicBarrier实例的await()方法,不管先在哪个线程中调用,该线程都会被屏障阻塞,直到CyclicBarrier实例的await()方法在另一个线程中被调用,之后屏障打开,两个线程剩下的代码接着执行。同CountDownLatch工具类相似的是,如果创建CyclicBarrier实例时传入的参数是3,而现在只有两个线程调用CyclicBarrier实例的await()方法,也就是只有两个线程会到达屏障,所有线程会一直被阻塞,因为还在等待第三个线程到达屏障,而一直等不到。

CyclicBarrier工具类还有一个构造器CyclicBarrier(int parties, Runnable barrierAction),需要传入一个正整数和一个Runnable对象,表示当屏障打开时,优先执行此Runnable对象。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值