【追女神】VS Java Future
你是一位痴情的程序员(主线程),你有一位喜欢的女神(任务目标)。
你终于鼓起勇气,发了条微信表白:“小美,其实,我喜欢你很久了,你可以做我女朋友吗?”(提交任务,等待女神回复)。
你知道她可能不会立刻回复,于是你继续敲代码、改bug。(主线程继续干活)。
你忐忑不安,你偶尔偷瞄手机看看有没有回复。(isDone()检查任务状态)。
你迫不及待,点开女神的聊天界面等待回复消息(get())。
接下来可能会有一下几种情况发生:
- 女神说喜欢你:你收获爱情(任务成功)
- 女神说你是好人但不合适:表白失败(任务异常)
- 女神被别人追到手,被截胡。(任务中断)
- 女神太久不回你?你决定放弃:不打算做舔狗了。(任务超时超时 or 取消)
| 追女神 | **Java Future ** |
|---|---|
| 给女神发表白微信 | 提交异步任务(Callable) |
| 她正在思考中(读消息) | 后台线程处理任务 |
| 你继续做自己的事,写代码或者看短剧 | 主线程不阻塞 |
| 偷看手机,查看女神状态 | future.isDone() |
| 打开聊天界面等待女神回复 | future.get() |
| 女神同意了,表白成功,抱得美人归 | 成功获取结果 |
| 女神拒绝了,表白失败 | 抛出 ExecutionException |
| 女神超过你等待时长,你不想等了 | TimeoutException |
| 你点击“撤回表白” | future.cancel(true) |
需求设计:Future 要实现什么功能?
功能点拆解:
| 功能 | 方法设计 |
|---|---|
| 提交任务异步执行 | submit(task) |
| 阻塞等待结果 | get()方法 |
| 支持超时等待 | get(timeout) |
| 支持取消任务 | cancel() |
| 抛出异常 | get()中处理异常 |
| 可检查状态 | isDone()、isCancelled() |
Future 接口是怎么设计的?
public interface Future<V> {
//阻塞拿结果
V get() throws InterruptedException, ExecutionException;
//限时等待结果,超时抛出异常
V get(long timeout, TimeUnit unit) throws ...;
//尝试终止任务,只是一种通知
boolean cancel(boolean mayInterruptIfRunning);
//任务是否取消
boolean isCancelled();
//任务是否完成,正常完成、取消、异常都算完成
boolean isDone();
}
自己动手实现 MyFutureTask
package com.omy.concurrent.fucture;
import java.util.Objects;
import java.util.concurrent.*;
public class MyFutureTask<V> implements Runnable, Future<V> {
private Callable<V> callable;
private V result;
private Throwable exception;
private Thread runner;
private volatile boolean done;
private volatile boolean canceled;
private final Object lock = new Object();
public boolean isCanceled() {
return canceled;
}
public MyFutureTask(Callable<V> callable) {
Objects.requireNonNull(callable, "Callable cannot be null")
this.callable = callable;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
synchronized (lock) {
if (isDone() || isCanceled()) {
return false;
}
canceled = true;
done = true;
if (mayInterruptIfRunning) {
Thread t = runner;
if (t != null) {
t.interrupt();
}
}
lock.notifyAll();
return true;
}
}
@Override
public boolean isCancelled() {
return canceled;
}
@Override
public boolean isDone() {
return done;
}
@Override
public V get() throws InterruptedException, ExecutionException {
synchronized (lock) {
while (!isDone() && !isCanceled()) {
lock.wait();
}
if (isCanceled()) {
throw new IllegalStateException("Task is cancelled");
}
if (exception != null) {
throw new ExecutionException("Task failed", exception);
}
return result;
}
}
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
if (timeout <= 0 || unit == null) {
throw new IllegalArgumentException("Timeout and unit must be valid");
}
long deadline = System.nanoTime() + unit.toNanos(timeout);
synchronized (lock) {
while (!isDone() && !isCanceled()) {
long remaining = deadline - System.nanoTime();
if (remaining <= 0L) {
throw new TimeoutException("Task timeout");
}
long millis = remaining / 1_000_000L;
int nanos = (int) (remaining % 1_000_000L);
try {
lock.wait(millis, nanos);
} catch (InterruptedException e) {
if (isCanceled()) {
throw new IllegalStateException("Task is cancelled");
}
throw e;
}
}
if (isCanceled()) {
throw new IllegalStateException("Task is cancelled");
}
if (exception != null) {
throw new ExecutionException("Task failed", exception);
}
return result;
}
}
@Override
public void run() {
synchronized (lock) {
runner = Thread.currentThread();
if (canceled) {
return;
}
}
try {
V ret = callable.call();
synchronized (lock) {
done = true;
result = ret;
exception = null;
lock.notifyAll();
}
} catch (Throwable ex) {
synchronized (lock) {
done = true;
result = null;
exception = ex;
lock.notifyAll();
}
} finally {
synchronized (lock) {
runner = null;
}
}
}
}
package com.omy.concurrent.fucture;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
@Slf4j
public class FutureDemo {
static class Xiao3 extends Thread{
Thread thread;
public Xiao3(Thread thread) {
Thread.currentThread().setName("小三");
this.thread = thread;
}
@Override
public void run(){
log.info("小三插足,女神被截胡了");
thread.interrupt();
}
}
public static void main(String[] args) {
Callable<String> callable = () -> {
while (!Thread.currentThread().isInterrupted()) {
for (int i = 0; i < 3; i++) {
log.info("女神思考中...");
TimeUnit.SECONDS.sleep(1);
}
break;
}
return "我也喜欢你";
};
MyFutureTask<String> futureTask = new MyFutureTask<>(callable);
Thread girlThread = new Thread(futureTask, "女神");
girlThread.start();
Thread.currentThread().setName("小帅");
try {
String result = futureTask.get(5, TimeUnit.SECONDS);
log.info("女神同意,表白成功:{}", result);
} catch (InterruptedException e) {
log.error("表白被截胡,表白中断", e);
} catch (ExecutionException e) {
log.error("女神拒绝,表白被拒", e);
} catch (TimeoutException e) {
log.error("表白超时", e);
}
log.info("表白结束");
}
}
1万+



被折叠的 条评论
为什么被折叠?



