JAVA多线程设计模式篇 10、Future 模式——兄弟,放一百二十个心,到时候来提货

Future模式是多线程开发中常见的设计模式,它的核心思想是异步调用。对于Future模式来说,它无法立即返回你需要的数据,但是它会返回一个契约,将来你可以凭借这个契约去获取你需要的信息。

  • 传统的同步方法
    调用一段耗时的程序。当客户端发出call请求,这个请求需要很长的一段时间才会返回,客户端一直在等待直到数据返回随后再进行其他任务的处理。
  • Future模式
    客户端在得到这个返回结果后并不急于对其进行处理而是调用其他业务逻辑,充分利用等待时间,在完成其他业务处理后,再使用返回比较慢的Future数据。这样在整个调用中就不存在无谓的等待,充分利用所有的时间片,从而提高了系统响应速度。

1. Future模式的核心角色

Funture模式 使用代理模式,在FutureData里持有了 RealData 对象。 Data、RealData、FutureData 共同组成代理模式。

1.1 定义Data接口

public interface Data {
    String get();
}

1.2 定义RealData

RealData的构造花费很多时间。是真实的结果数据。

public class RealData implements Data {
    private String result;

    public RealData(String request) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        result = "这是你的货";
    }

    public String get() {
        return result;
    }
}

1.3 定义FutureData

FutureData持有RealData,当客户端调用get()方法时,会阻塞等待。那它阻塞等待什么呢?
等待ready信号。当服务端完成了数据的获取计算,就会调用setResult(RealData realData)方法,此时会将realdata设入,并设置isReady为真,唤醒get()方法。

 
public class FutureData implements Data {
 
	protected RealData realData = null;
 
	protected boolean isReady = false;
 
	// 进行同步控制
	public synchronized void setResult(RealData realData) {
		if (isReady) {
			return;
		}
		this.realData = realData;
		isReady = true;
		notifyAll();
	}
 
	// 实际调用返回RealData的数据
	@Override
	public synchronized String get() {
		while (!isReady) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return realData.get();
	}
}

1.4 服务端程序

服务端程序在接收请求后,立即启动一个新线程去取货,并交付futureData给客户端。

public class Server {
    public Data request(final String request) {
        final FutureData futureData = new FutureData();

        new Thread(new Runnable() {
            public void run() {
                RealData realData = new RealData(request);
                futureData.setResult(realData);
            }
        }).start();

        return futureData;
    }
}

1.5 示例

public class Main {

    public static void main(String[] args) {
        Server server= new Server();
        Data data = server.request("给我一箱货");
		//这里客户端可以做很多其他的运算,不浪费时间。
		dosomething_log();
		dosomething_db();
		//去拿货了
        String result = data.get();
        System.out.println(result);
    }
}

总结

Future 模式是一种异步方法。可以合理安排分配时间,考虑许多IO任务,在等待的时候可以充分利用CPU。Future 模式 将调用与执行分离。
JDK中JUC的Callable Future FutureTask 即 使用了Future 模式。 可以参考 《JAVA多线程进阶篇 10、JUC线程池之Callable Future FutureTask》

多线程系列在github上有一个开源项目,主要是本系列博客的实验代码。

https://github.com/forestnlp/concurrentlab

如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。

您的支持是对我最大的鼓励。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟空学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值