import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
*
*
保护一个重要(代码)部分防止一次超过 N 个线程进入。
在N 个线程之间发送信号。
* @author fansxnet
*
*/
public class SemaphoreTest {
public static void main(String[] args) {
// 线程池
ExecutorService exec = Executors.newCachedThreadPool();
// 只能5个线程同时访问
final Semaphore semp = new Semaphore(5);
// 模拟20个客户端访问
for (int index = 0; index < 20; index++) {
final int NO = index;
Runnable run = new Runnable() {
public void run() {
try {
// 获取许可
semp.acquire();
System.out.println(System.currentTimeMillis()+":Accessing: " + NO);
Thread.sleep((long) (Math.random() * 10000));
// 访问完后,释放 ,如果屏蔽下面的语句,则在控制台只能打印5条记录,之后线程一直阻塞
semp.release();
} catch (InterruptedException e) {
}
}
};
exec.execute(run);
}
// 退出线程池
exec.shutdown();
}
}
1489915492740:Accessing: 0
1489915492746:Accessing: 1
1489915492748:Accessing: 2
1489915492749:Accessing: 3
1489915492749:Accessing: 4
1489915493792:Accessing: 5
1489915495852:Accessing: 6
1489915497145:Accessing: 8
1489915497299:Accessing: 7
1489915497681:Accessing: 9
1489915499427:Accessing: 10
1489915501457:Accessing: 11
1489915503579:Accessing: 12
1489915503953:Accessing: 13
1489915504278:Accessing: 14
1489915504941:Accessing: 15
1489915505704:Accessing: 16
1489915506731:Accessing: 17
1489915507014:Accessing: 18
1489915507420:Accessing: 19
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。
* @author fansxnet 该程序用来模拟发送命令与执行命令,主线程代表指挥官,新建3个线程代表战士,战士一直等待着指挥官下达命令,
* 若指挥官没有下达命令,则战士们都必须等待。一旦命令下达,战士们都去执行自己的任务,指挥官处于等待状态,战士们任务执行完毕则报告给
* 指挥官,指挥官则结束等待。
*/
public class CountdownLatchTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool(); // 创建一个线程池
final CountDownLatch cdOrder = new CountDownLatch(1);// 指挥官的命令,设置为1,指挥官一下达命令,则cutDown,变为0,战士们执行任务
final CountDownLatch cdAnswer = new CountDownLatch(3);// 因为有三个战士,所以初始值为3,每一个战士执行任务完毕则cutDown一次,当三个都执行完毕,变为0,则指挥官停止等待。
for (int i = 0; i < 3; i++) {
Runnable runnable = new Runnable() {
public void run() {
try {
System.out.println("线程" + Thread.currentThread().getName() + "正准备接受命令");
cdOrder.await(); // 战士们都处于等待命令状态
System.out.println("线程" + Thread.currentThread().getName() + "已接受命令");
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName() + "回应命令处理结果");
cdAnswer.countDown(); // 任务执行完毕,返回给指挥官,cdAnswer减1。
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);// 为线程池添加任务
}
try {
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName() + "即将发布命令");
cdOrder.countDown(); // 发送命令,cdOrder减1,处于等待的战士们停止等待转去执行任务。
System.out.println("线程" + Thread.currentThread().getName() + "已发送命令,正在等待结果");
cdAnswer.await(); // 命令发送后指挥官处于等待状态,一旦cdAnswer为0时停止等待继续往下执行
System.out.println("线程" + Thread.currentThread().getName() + "已收到所有响应结果");
} catch (Exception e) {
e.printStackTrace();
}
service.shutdown(); // 任务结束,停止线程池的所有线程
}
}
线程pool-1-thread-1正准备接受命令
线程pool-1-thread-2正准备接受命令
线程pool-1-thread-3正准备接受命令
线程main即将发布命令
线程main已发送命令,正在等待结果
线程pool-1-thread-1已接受命令
线程pool-1-thread-2已接受命令
线程pool-1-thread-3已接受命令
线程pool-1-thread-1回应命令处理结果
线程pool-1-thread-2回应命令处理结果
线程pool-1-thread-3回应命令处理结果
线程main已收到所有响应结果
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
* 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。
* 在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。 因为该 barrier *
* 在释放等待线程后可以重用,所以称它为循环 的 barrier。
* 需要所有的子任务都完成时,才执行主任务,这个时候就可以选择使用CyclicBarrier。
*
* @author fansxnet
*
*/
public class CyclicBarrierTest {
private static final int STUDENT_NUM = 10;
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable teacher = new Runnable() {
// 当所有线程到达barrier时执行
public void run() {
System.out.println("同学们,咱们出发");
}
};
final CyclicBarrier cb = new CyclicBarrier(STUDENT_NUM, teacher);
ExecutorService executor = Executors.newFixedThreadPool(STUDENT_NUM);
for (int i = 0; i < STUDENT_NUM; i++) {
final int studentId = i;
executor.submit(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
System.out.println("学生:" + studentId + " 等待");
// 线程在这里等待,直到所有线程都到达barrier。
cb.await();
System.out.println("学生:" + studentId + " 出发");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}
学生:1 等待
学生:0 等待
学生:2 等待
学生:3 等待
学生:4 等待
学生:5 等待
学生:6 等待
学生:7 等待
学生:8 等待
学生:9 等待
同学们,咱们出发
学生:9 出发
学生:1 出发
学生:4 出发
学生:3 出发
学生:2 出发
学生:0 出发
学生:8 出发
学生:7 出发
学生:6 出发
学生:5 出发
看看 http://blog.csdn.net/defonds/article/details/44021605/