package com;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* FutureTask 类似于Runnable, 但是其执行可以获取到执行的结果
*
* 并可以通过其get()方法来获取到该结果,当然该get方法是一个阻塞方法;
*
* 也就是当放获取到了数据的时候,我们可能并不想用用该数据, 所以可以在需要该数据的时候再调用该对象的
*
* get方法
*
* 情景: 当我们在需要进行预加载的时候,就可以用该该方式
*
*
* CountDowmLatch是一种灵活的闭锁实现,包含一个计数器,该计算器初始化为一个正数,表示需要等待事件
*
* 的数量。countDown方法递减计数器,表示有一个事件发生,而await方法等待计数器到达0,表示所有需要等待的事情都已经完成。
*
* ExecutorService 中 的invokeAll 同样具有这样的作用, 使结果统一返回, 但是其执行也是需要统一开始执行
*
* 情景: 当所有的线程执行完成之后,在同一执行其他的操作
*/
public class CountDowmLatchDemo {
FutureTask<String> futureTast = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(3000);
return "预加载执行了3秒钟";
}
});
public static void main(String[] args) throws InterruptedException, ExecutionException {
//doFutureTask();
doCountDowmLathc();
}
CountDownLatch mLatch = new CountDownLatch(3);
private static void doCountDowmLathc() throws InterruptedException{
final CountDowmLatchDemo demo = new CountDowmLatchDemo();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("爸爸赶过来用时:2秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
demo.mLatch.countDown();//标记执行完成
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(4000);
System.out.println("妈妈赶过来用时:4秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
demo.mLatch.countDown();//标记执行完成
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
System.out.println("儿子赶过来用时:3秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
demo.mLatch.countDown();//标记执行完成
}
}).start();
long startTime = System.currentTimeMillis();
demo.mLatch.await(); // 等待三个人都到齐了在执行
System.out.println("到齐了, 吃饭,共用时:" + (System.currentTimeMillis() - startTime) / 1000 + "秒");
}
private static void doFutureTask() throws InterruptedException,
ExecutionException {
CountDowmLatchDemo demo = new CountDowmLatchDemo();
Thread thread = new Thread(demo.futureTast);
thread.start();//开始进行预加载
//加载其他的东西
Thread.sleep(2000);
System.out.println("加载其他东西:用时2秒");
long startTime = System.currentTimeMillis();
System.out.println("获取预加载的数据,其用时:" + demo.futureTast.get());
long allTime = System.currentTimeMillis() - startTime;
System.out.println("执行时间:" + allTime / 1000 + "秒");
}
}