Futuer 模式 和 Callable

Futuer 模式

Futrure模式:对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果是再取真实的结果。

你可以那做饭来比喻,假如你突然想做饭,但是没有厨具,也没有食材。网上购买厨具比较方便,食材去超市买更放心。

实现分析:在快递员送厨具的期间,我们肯定不会闲着,可以去超市买食材。所以,在主线程里面另起一个子线程去网购厨具。然后等什么都准备好了,才能开始做饭。

公共数据接口,FutureData和RealData都要实现。

public interface Data {
	public abstract String getRequest();
}

FutureData,当有线程想要获取RealData的时候,程序会被阻塞。等到RealData被注入才会使用getReal()方法。

public class FurureData implements Data {

	public volatile static boolean ISFLAG = false;
	private RealData realData;

	public synchronized void setRealData(RealData realData) {
		// 如果已经获取到结果,直接返回
		if (ISFLAG) {
			return;
		}
		// 如果没有获取到数据,传递真是对象
		this.realData = realData;
		ISFLAG = true;
		// 进行通知
		notify();
	}

	@Override
	public synchronized String getRequest() {
		while (!ISFLAG) {
			try {
				wait();
			} catch (Exception e) {

			}
		}
		// 获取到数据,直接返回
		return realData.getRequest();
	}

}

真实数据RealData

public class RealData implements Data {
	private String result;

	public RealData(String data) {
		System.out.println("正在使用data:" + data + "网络请求数据,耗时操作需要等待.");
		try {
			Thread.sleep(3000);
		} catch (Exception e) {

		}
		System.out.println("操作完毕,获取结果...");
		result = "余胜军";
	}

	@Override
	public String getRequest() {
		return result;
	}

FutureClient 客户端

public class FutureClient {
    public Data request(String queryStr) {
        FurureData furureData = new FurureData();

        new Thread(()->{
            RealData realData = new RealData(queryStr);
            furureData.setRealData(realData);
        }).start();

        return furureData;
    }
}

调用者:

public class Main {

	public static void main(String[] args) {
		FutureClient futureClient = new FutureClient();
		Data request = futureClient.request("请求参数.");
		System.out.println("请求发送成功!");
		System.out.println("执行其他任务...");
		String result = request.getRequest();
		System.out.println("获取到结果..." + result);
	}

}

调用者请求资源,client.request(“name”); 完成对数据的准备

当要获取资源的时候,data.getResult() ,如果资源没有准备好isReady = false;那么就会阻塞该线程。直到资源获取然后该线程被唤醒。

Callable获取任务结果

在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。Callable用来执行任务,产生结果。

public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        Future<Integer> future = executor.submit(new AddNumberTask());
        System.out.println(Thread.currentThread().getName() + "线程执行其他任务");
        Integer integer = future.get();
        System.out.println(integer);

        // 关闭线程池
        if (executor != null){
            executor.shutdown();
        }

    }
}

class AddNumberTask implements Callable<Integer> {
    public AddNumberTask() {

    }

    public Integer call() throws Exception {
        System.out.println("####AddNumberTask###call()");
        Thread.sleep(5000);
        return 5000;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值