多线程--Future模式

博客介绍了Future模式,当任务执行时间长会阻塞其他任务、降低系统吞吐量,而Future模式可避免此问题。还提到使用callBack方式的好处,即任务处理完成可自动调用consumer方法,无需等待get数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Future模式

  1. 作用: 当任务执行时间很久,导致阻塞其它任务的执行,降低了系统的吞吐量。而Future则不阻塞任务的执行。
/**
 * 真正任务执行接口.
 */
public interface FutureTask<T> {
	T call();
}

/**
	* 作为外部得到任务执行结果的接口
*/
public interface Future<T> {
// 真正获取数据的接口.
T get() throws InterruptedException;
}

public class AsyncFuture<T> implements Future<T> {
	private volatile boolean done = false; // 任务是否执行结束

	private T result; //结果

	/**
	* 真正获取数据时调用
	* @return
	* @throws InterruptedException
	*/
	@Override
	public T get() throws InterruptedException { synchronized (this) {
		while (!done) {
			this.wait();
		}
 }

return result;
}


/**
* 数据生产好时调用
* @param result
*/
public void done(T result) { synchronized (this) {
		this.result = result;
		this.done = true;
		this.notifyAll(); // 可能get和done不是一个thread.
	} 
}
}

/**
 * 提交任务
 */
public class FutureService {
	public <T> Future<T> submit(final FutureTask<T> task) {
		AsyncFuture<T> asyncFuture = new AsyncFuture<>();
		new Thread(() -> { 
			T result = task.call(); // 就是真正处理数据的线程.
			asyncFuture.done(result); // 线程处理好数据时, 返回给Future.
		}).start();
		
		return asyncFuture;
}}

/**
* Future测试
*/
public class FutureDemo {
	public static void main(String[] args) throws InterruptedException {
		FutureService futureService = new FutureService();
		/*
		* 1. 调用FutureService.submit(FutureTask task) 方法, 启动线程执行任务;
		* 2. 任务执行完成, 把结果给AsyncFuture.done(T result).
		* 3. 因为启用了其它的线程去执行任务, 主线程可以做其它的事情.
		* 4. 真正需要数据的时候, 使用Future.get(), 得到任务的返回数据. 若任务未执行完成, 则wait. 有结果则直接返回.
		*/
		Future<String> future = futureService.submit(() -> { 
			try {
				Thread.sleep(5_000);
			} catch (InterruptedException e) { e.printStackTrace();
			}
			return "Finish!";
		});

		System.out.println("================");
		System.out.println(" do other thing......");
		Thread.sleep(1_000);
		//get(): 获取真正的结果: 若数据准备好了, 可以直接获取; 数据还没有准备好, 则wait.
		System.out.println("result: " + future.get());
	}
}
  1. 使用callBack方式
    1. 好处:可以根据传入的consumer, 任务处理完成了自动调用consumer方法。不需要我们再次去get数据。而可能造成的任务未完成时的等待。
public <T> Future<T> submit(final FutureTask<T> task, Consumer<T> consumer) {
    AsyncFuture<T> asyncFuture = new AsyncFuture<>();
    new Thread(() -> {        T result = task.call(); // 就是真正处理数据的线程.
        asyncFuture.done(result); // 线程处理好数据时, 返回给Future.
        consumer.accept(result); // 回调
    }).start();

    return asyncFuture;
}

测试:
Future<String> future = futureService.submit(() -> { 
			try {
				Thread.sleep(5_000);
			} catch (InterruptedException e) { e.printStackTrace();
			}
			return "Finish!";
		}, System.out::println); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值