您的位置:首页 > 其它

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

2015-07-20 18:22 316 查看
并发工具类在java.util.concurrent包下。常用的有CountDownLatch、CyclicBarrier,用它们可以控制并发流程。

1.CountDownLatch探究:

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

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

使用join:

public class JoinTest {
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工具类:主要用到await()方法和countDown()方法

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探究:主要用到int await()方法和

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实例await()方法的线程数小于创建CyclicBarrier实例时传入的参数,则调用CyclicBarrier实例await()方法的线程将一直阻塞,因为屏障打不开,但是其他线程可以接着执行,如果还有其他线程的话。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: