图中 Futures 就好比居民楼一层的信箱(每个信箱有房间编号),左侧的 t0,t2,t4 就好比等待邮件的居民,右侧的 t1,t3,t5 就好比邮递员
如果需要在多个类之间使用 GuardedObject 对象,作为参数传递不是很方便,因此设计一个用来解耦的中间类,这样不仅能够解耦【结果等待者】和【结果生产者】,还能够同时支持多个任务的管理

public class TestGuardedObjectV3 {public static void main(String[] args) {for (int i = 0; i < 3; i++) {GuardedObjectV3 v3 = Fetures.createFeture();new Thread(() -> {log.debug("waiting id({})...", v3.getId());log.debug("get response id({}): [{}] lines", v3.getId(), ((List<String>) v3.get()).size());}).start();new Thread(() -> {try {List<String> lines = download();log.debug("download complete id({})...", v3.getId());Fetures.complete(v3.getId(), lines);} catch (IOException e) {e.printStackTrace();}}).start();}}}class Fetures {private static final ConcurrentHashMap<Integer, GuardedObjectV3> FETURES = new ConcurrentHashMap<>();private static final AtomicInteger ID_GENERATOR = new AtomicInteger();public static GuardedObjectV3 createFeture() {// 为每个 GuardedObject 分配一个 idint id = ID_GENERATOR.incrementAndGet();GuardedObjectV3 v3 = new GuardedObjectV3(id);// 放入公共位置,将来异步响应返回时,根据编号获取FETURES.put(id, v3);return v3;}public static void complete(int id, Object response) {// 异步响应完成,根据编号获取并移除GuardedObjectV3 v3 = FETURES.remove(id);if (v3 != null) {v3.complete(response);}}}/*** 添加多任务处理*/class GuardedObjectV3 {private int id;private Object response;private final Object lock = new Object();public GuardedObjectV3(int id) {this.id = id;}public int getId() {return id;}public Object get() {synchronized (lock) {while (response == null) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}return response;}}public void complete(Object response) {synchronized (lock) {this.response = response;lock.notifyAll();}}}
