1 闭锁
- 闭锁:在完成某些运算时,只有其他所有线程的运算全部完成,当前运算才能继续执行
package JUC;
import java.util.concurrent.CountDownLatch;
/**
* 模拟多线程程序全线程运行结束时长
*
* @author Yorick
*
*/
public class CountDownLatchTest {
// 创建countDownLatch变量时传入的5是线程数量的计数器,每次启动并结束一个线程时需要从计数器中减1
final static CountDownLatch countDownLatch = new CountDownLatch(5);
public static void main(String[] args) {
long start = System.currentTimeMillis();
ThreadDemo4 demo4 = new ThreadDemo4(countDownLatch);
for (int i = 0; i < 5; i++) {
new Thread(demo4).start();
}
try {
// 等待所有线程结束
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Time:" + (end - start));
}
}
class ThreadDemo4 implements Runnable {
private CountDownLatch countDownLatch;
public ThreadDemo4(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
for (int i = 0; i < 500; i++) {
if (i % 20 == 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
} finally {
// 使用try-finally保证线程数可以被减1
countDownLatch.countDown();
}
}
}
2 Callable接口的实现
- 相较于实现
Runnable
接口的方式,方法可以有返回值,并且可以抛出异常 - 执行
Callable
方式,需要FutureTask
实现类的支持,用于接收运算结果。FutureTask
是Future
接口的实现类,FutureTask
也可以实现闭锁操作。
package JUC;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* 主从线程进行两部分运算,并获取结果(使用Callable接口创建线程实体)
*
* @author Yorick
*
*/
public class CallableTest {
public static void main(String[] args) {
// 分线程进行一部分运算
ThreadDemo5 demo5 = new ThreadDemo5();
// future用于获取最终的数据
FutureTask<Integer> future = new FutureTask<Integer>(demo5);
new Thread(future).start();
// 主线程进行另一部分运算
int sum = 1;
for (int i = 1; i < 10; i++) {
sum = sum * i;
}
System.out.println("sum* = " + sum);
try {
// 获取最终的数据(call方法的返回值),get之后的方法会被阻塞,等待call方法的返回值
// 因此,FutureTask也可以实现闭锁的操作
Integer result = future.get();
System.out.println("sum+ = " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ThreadDemo5 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
return sum;
}
}