Future 简单理解:先给你一张凭证,等结果出来后,你再来取。
package concurrent.future;
public interface Future<T> {
// 返回计算后的结果,该方法会陷入阻塞状态
T get() throws InterruptedException;
// 判断任务是否已经执行完成
boolean done();
}
package concurrent.future;
public interface FutureService<IN, OUT> {
// 提交不需要返回值的任务,Future.get 方法返回的将会是 null
Future<?> submit(Runnable runnable);
// 提交需要返回值的任务,其中 Task 接口代替了 Runnable 接口
Future<OUT> submit(Task<IN, OUT> task, IN input);
// 使用静态方法创建一个 FutureService 实例
static <T, R> FutureService<T, R> newService() {
return new FutureServiceImpl<>();
}
}
package concurrent.future;
@FunctionalInterface
public interface Task<IN, OUT> {
// 给定一个参数,经过计算返回结果
OUT get(IN input);
}
package concurrent.future;
public class FutureTask<T> implements Future<T> {
// 计算结果
private T result;
// 任务是否完成
private boolean isDone = false;
// 对应对象锁
private final Object Lock = new Object();
@Override
public T get() throws InterruptedException {
synchronized (Lock) {
// 当任务还没完成时,调用 get 方法会被挂起而进入阻塞
while (!isDone) {
Lock.wait();
}
// 返回最终计算结果
return result;
}
}
// 为 FutureTask 设置结算结果
protected void finish(T result) {
synchronized (Lock) {
if (isDone) {
return;
}
this.result = result;
this.isDone = true;
Lock.notifyAll();
}
}
// 返回当前任务是否已经完成
@Override
public boolean done() {
return isDone;
}
}
package concurrent.future;
import java.util.concurrent.atomic.AtomicInteger;
public class FutureServiceImpl<IN, OUT> implements FutureService<IN, OUT> {
// 线程名字前缀
private final static String FUTURE_THREAD_PREFIX = "FUTURE-";
private final AtomicInteger nextCounter = new AtomicInteger(0);
private String getNextName() {
return FUTURE_THREAD_PREFIX + nextCounter.getAndIncrement();
}
@Override
public Future<?> submit(Runnable runnable) {
final FutureTask<Void> future = new FutureTask<>();
new Thread(() -> {
runnable.run();
// 任务结束之后将 null 作为结果传给 future
future.finish(null);
}, getNextName()).start();
return future;
}
@Override
public Future<OUT> submit(Task<IN, OUT> task, IN input) {
final FutureTask<OUT> future = new FutureTask<>();
new Thread(() -> {
OUT result = task.get(input);
// 任务结束之后,将真实的结果通过 finish 方法传递给 future
future.finish(result);
}, getNextName()).start();
return future;
}
}
package concurrent.future;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) throws InterruptedException {
// 定义不需要返回值的 FutureService
FutureService<Void,Void> service = FutureService.newService();
Future<?> futrue = service.submit(() -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am finish done");
});
// futrue 方法会使当前线程进入阻塞
futrue.get();
// 定义有需要返回值的 FutureService
FutureService<String,Integer> service1 = FutureService.newService();
Future<Integer> future1 = service1.submit(input ->
{
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return input.length();
},"hello");
System.out.println(future1.get());
}
}
I am finish done
5
创作挑战赛
新人创作奖励来咯,坚持创作打卡瓜分现金大奖
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/124281896
内容来源于网络,如有侵权,请联系作者删除!