JAVA 多线程同步工具类总结(一)

2014-11-24 10:43:50 · 作者: · 浏览: 3

CountDownLatch 闭锁:可以延迟线程的进度,直到锁到达终止状态。闭锁的作用相当于一扇门,在锁到达终止状态之前这扇门一直是关闭的。当锁到达终止状态时,允许所有线程通过。CountDownLatch 有一个初始值,通过调用 countDown 可以减少该值,一直到 0 时到达终止状态。

FutureTask 用于执行一个可返回结果的长任务,任务在单独的线程中执行,其他线程可以用 get 方法取任务结果,如果任务尚未完成,线程在 get 上阻塞。

Semaphore 用于控制同时访问某资源,或同时执行某操作的线程数目。信号量有一个初始值即可以分配的信号量总数目。线程任务开始前先调用 acquire 取得信号量,任务结束后调用 release 释放信号量。在 acquire 是如果没有可用信号量,线程将阻塞在 acquire 上,直到其他线程释放一个信号量。

CyclicBarrier 栅栏用于多个线程多次迭代时进行同步,在一轮任务中,任何线程完成任务后都在 barrier 上等待,直到所有其他线程也完成任务,然后一起释放,同时进入下一轮迭代。
CountDownLatch 的例子:
[java]
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;


public class DemoOfLatch {

// 利用闭锁 CountDownLatch 控制主线程和子线程的同步
public static void main(String[] args) {

int numberOfThread = 5;
final CountDownLatch startLatch = new CountDownLatch(1); // 用于控制子线程开始
final CountDownLatch stopLatch = new CountDownLatch(numberOfThread); // 用于子线程计数
final AtomicInteger count = new AtomicInteger(0); // 用于分配子线程唯一标识

System.out.println("Main thread start...");

for ( int i=0; i Thread thread = new Thread( new Runnable() {

@Override
public void run() {
int tid = count.getAndIncrement();
try {
// 等代主线程打开启动信号
startLatch.await();
System.out.printf("Thread %d started...%n", tid);
int duration = (int)(Math.random() * 5000);
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
} finally {
System.out.printf("Thread %d stoped...%n", tid);
// 线程终止前减少线程计数
stopLatch.countDown();
}
}

});
thread.start();
}

// 在放行子线程之前做点什么别的事情
System.out.println("Main thread do preparation work for child threads...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}

// 打开闭锁放行所有子线程
System.out.println("Main thread let child threads go...");
startLatch.countDown();

try {
// 等待子线程计数降为 0 即所有子线程执行完毕
System.out.println("Main thread wait for all child threads...");
stopLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("Main thread exit...");
}

}

FutureTask 的例子:
[java]
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;


public class DemoOfFutureTask {

public static void main(String[] args) {

// 创建一个 Future Task 用于并发执行长任务
final FutureTask future = new FutureTask( new Callable() {

@Override
public Movie call() throws Exception {
System.out.println(