1. CountDownLatch应用
场景
日常操作:老爸出去买菜,老妈去逛街买衣服,然后两人集合一起打车回家。
实现
public class ConcurrentTest {
private static final CountDownLatch cdl = new CountDownLatch(2);
public static void main(String[] args) {
ThreadPoolExecutor tpe = new ThreadPoolExecutor(2,
2,
10,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10));
tpe.allowCoreThreadTimeOut(true);
tpe.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
System.out.println("老爸买菜");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
cdl.countDown();
}
}
});
tpe.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
System.out.println("老妈逛街买衣服");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
cdl.countDown();
}
}
});
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("一起坐车回家");
}
}
总结:
CountDownLatch的特点等待前n个线程执行完之后再执行。但是缺点就是一次性的,不可以重置。
2. CyclicBarrier应用
场景
日常操作:老爸陪老妈逛街一起出门打车,老爸在家先收拾家务,老妈化妆,然后一起打车出门。
实现
public class CyclicBarrierTest {
private static final CyclicBarrier cb = new CyclicBarrier(2, new Runnable() {
@Override
public void run() {
System.out.println("一起打车出门");
}
});
public static void main(String[] args) {
ThreadPoolExecutor tpe = new ThreadPoolExecutor(2,
2,
20,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10));
tpe.allowCoreThreadTimeOut(true);
tpe.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println("老爸收拾家务");
cb.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
});
tpe.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println("老妈化妆");
cb.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
});
}
}
结果:
老爸收拾家务
老妈化妆
一起打车出门
总结:
多个线程到达指定的屏障点,才可以执行。最后一个线程到达屏障后,最后执行的线程在构造器传入。还可以通过reset方法还可以重置屏障为初始化状态。
3. Semaphore应用
场景
桥只能允许两个人,多一个人上桥就会落水,所以只能保证桥上的人流量为2人。
实现
public class SemaphoreTest {
private static final Semaphore semaphore = new Semaphore(2);
public static void main(String[] args) {
ThreadPoolExecutor tpe = new ThreadPoolExecutor(2,
2,
20,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10));
tpe.allowCoreThreadTimeOut(true);
tpe.execute(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 上桥");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
tpe.execute(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 上桥");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
tpe.execute(new Runnable() {
@Override
public void run() {
try {
semaphore.release();
System.out.println(Thread.currentThread().getName() + " 下桥");
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 上桥");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
结果:
pool-1-thread-1 上桥
pool-1-thread-2 上桥
pool-1-thread-1 下桥
pool-1-thread-1 上桥
4. Exchanger应用
场景
两支球队,相互交易球员,一个交易出勒布朗詹姆斯,一个交易出斯蒂芬库里。
实现
public class ExchangerTest {
private static final Exchanger<String> exchanger = new Exchanger<String>();
public static void main(String[] args) {
ThreadPoolExecutor tpe = new ThreadPoolExecutor(2,
2,
15,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10));
tpe.allowCoreThreadTimeOut(true);
tpe.execute(new Runnable() {
@Override
public void run() {
try {
String outputStr = " 勒布朗詹姆斯";
String inputStr = exchanger.exchange(outputStr);
System.out.println(Thread.currentThread().getName() + " 交易进来" + inputStr);
System.out.println(Thread.currentThread().getName() + " 交易出去" + outputStr);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
tpe.execute(new Runnable() {
@Override
public void run() {
try {
String outputStr = " 斯蒂芬库里";
String inputStr = exchanger.exchange(outputStr);
System.out.println(Thread.currentThread().getName() + " 交易进来" + inputStr);
System.out.println(Thread.currentThread().getName() + " 交易出去" + outputStr);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
结果:
pool-1-thread-1 交易进来 斯蒂芬库里
pool-1-thread-2 交易进来 勒布朗詹姆斯
pool-1-thread-1 交易出去 勒布朗詹姆斯
pool-1-thread-2 交易出去 斯蒂芬库里
网友评论