循环屏障 CyclicBarrier 精确控制多个线程同一时刻并发执行。
| 关键方法 | 说明 |
|---|---|
| CyclicBarrier(intparties) | 构造函数,设置并发执行线程的个数 |
| CyclicBarrier(intparties, Runnable barrierAction) | 构造函数,设置并发执行个数;第二个Runnable参数会在并发执行之前优先执行。 |
| await() | 执行后阻塞线程,直到阻塞的个数达到构造函数中设置的并发个数。 |
static CyclicBarrier barrier = new CyclicBarrier(4, new Runnable() {
public void run() {
System.out.println("跑...");
}
});
static AtomicInteger number = new AtomicInteger();
static Runnable runner = new Runnable() {
public void run() {
int num = number.addAndGet(1);
System.out.println(num+" 号选手准备完毕");
try {barrier.await();} catch (Exception e) {}
System.out.println(num+" 号选手奔跑...");
}
};
public static void main( String[] args ) throws Exception{
System.out.println("各就各位,预备...");
for(int i = 0; i<3; i++)
new Thread(runner).start();
barrier.await();
}
在多线程环境下,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。通过CountDownLatch 可以控制某个线程的执行时机。
| 关键方法 | 说明 |
|---|---|
| CountDownLatch(int count) | 构造函数中确定计数值 |
| await() | 若计数值不为0,则阻塞等待,直到计数值为0,线程中断后执行该操作会抛异常。 |
| countDown() | 计数值减一 |
Main 线程等待5个线程执行完毕后,最后打印
static CountDownLatch latch = new CountDownLatch(3);
public static void main( String[] args ) throws Exception{
for(int i = 0; i<3;i++)
new Thread(new Runnable() {
public void run() {
try {Thread.sleep(1000);} catch (Exception e) {}
System.out.println(Thread.currentThread().getName()+" 计算完毕");
latch.countDown();
}
}).start();
latch.await();
System.out.println("main 统计结果");
}
限制并发量,保护一个重要的(代码)部分防止一次超过 N 个线程进入。
public Semaphore(int permits):设置最大阈值
public void acquire() : 获取一个值
public void release() : 释放一个值
public void acquire(int permits):获取permits个值
public void release(int permits):释放permits个值
// 只允许一个线程同时进入
Semaphore semaphore = new Semaphore(1);
//critical section
semaphore.acquire();
...
semaphore.release();
// 允许3个线程同时进入
Semaphore semaphore = new Semaphore(10);
//critical section
semaphore.acquire(3);
...
semaphore.release(3);
Exchanger 可以让两个线程互相交换对象。
static Exchanger exchanger = new Exchanger();
public static void main(String[] arg) throws Exception {
new Thread(new Runnable() {
public void run() {
try {
String receive =(String)exchanger.exchange("A");
printf(System.currentTimeMillis()+":"+Thread.currentThread().getName()+" send: A receive:"+receive);
} catch (Exception e) {}
} }).start();
Thread.sleep(5000);
String r = (String) exchanger.exchange("B");
printf(System.currentTimeMillis()+":"+Thread.currentThread().getName()+" send: B receive:"+r);
}
