闭锁(CountDownLatch)
- 闭锁就相当于一个大门,只有等所有线程都到达之后,门才会开。例如:我约了其它三个人一起打麻将,之后等我们四个人都到了之后,才能开始打麻将。
private static void testCountDownLatch() {
final CountDownLatch start = new CountDownLatch(1);
final CountDownLatch end = new CountDownLatch(3);
new Thread() {
@Override
public void run() {
try {
start.await();
System.out.println("CountDownLatch Thread1 working...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
end.countDown();
}
}
}.start();
new Thread() {
@Override
public void run() {
try {
start.await();
System.out.println("CountDownLatch Thread2 working...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
end.countDown();
}
}
}.start();
new Thread() {
@Override
public void run() {
try {
start.await();
System.out.println("CountDownLatch Thread3 working...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
end.countDown();
}
}
}.start();
System.out.println("CountDownLatch Threads start...");
start.countDown();
try {
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("CountDownLatch Threads finish...");
}
FutureTask
- FutureTask的get方法,如果还没运行结束时,会一直阻塞,直到有结果。
private static void testFutureTask() {
FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
return "FutureTask test...";
}
});
try {
future.run();
System.out.println(future.get());
} catch (Exception e) {
e.printStackTrace();
}
}
Semaphore信号量
- 信号量在使用时,要先获取信号量,如果获取到了,才能继续执行,否则将一直阻塞,直到获取到信号量。
private static void testSemaphore() {
Semaphore semaphore = new Semaphore(1);
try {
semaphore.acquire();
System.out.println("Semaphore test...");
semaphore.release();
} catch (Exception e) {
e.printStackTrace();
}
}
栅栏
- 栅栏跟闭锁有点类似。不过闭锁是等待外部事件的触发,而栅栏是所有线程相互等待,直到某个点,栅栏才打开。
public class TestBarrier {
private Board mainBoard;
private CyclicBarrier barrier;
private int nums = 5;
private int dealCount = 0;
public TestBarrier(final int cpuNum) {
mainBoard = new Board();
barrier = new CyclicBarrier(cpuNum, new Runnable() {
@Override
public void run() {
dealCount += cpuNum;
if (dealCount != nums) {
System.out.println("数据尚未处理完...");
} else {
System.out.println("Result=" + mainBoard.getResult());
}
}
});
for (int i = 0; i < cpuNum; i++) {
new Thread(new Worker(mainBoard, i + 1)).start();
}
}
/**
* 具体算法
*
* @author HuangXiquan
*
*/
private class Worker implements Runnable {
private Board board;
private int number;
public Worker(Board board, int number) {
this.board = board;
this.number = number;
}
@Override
public void run() {
System.out.println("Worker compute number=" + number);
board.setResult(number - 1, number * number);
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
private class Board {
private int[] result = new int[nums];
public void setResult(int index, int value) {
result[index] = value;
}
public int getResult() {
int value = 0;
for (int i = 0; i < result.length; i++) {
value += result[i];
}
return value;
}
}
public static void main(String[] args) {
int cpuNum = Runtime.getRuntime().availableProcessors();
System.out.println("cpuNum=" + cpuNum);
new TestBarrier(cpuNum);
}
}