1-5并发编程之Callable与Future模式

Callable

在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。我们一般只能采用共享变量或共享存储区以及线程通信的方式实现获得任务结果的目的。

不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操作。Callable用来执行任务,产生结果,而Future用来获得结果。

Future常用方法

V get() :获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。

V get(Long timeout , TimeUnit unit) :获取异步执行结果,如果没有结果可用,此方法会阻塞,但是会有时间限制,如果阻塞时间超过设定的timeout时间,该方法将抛出异常。

boolean isDone() :如果任务执行结束,无论是正常结束或是中途取消还是发生异常,都返回true。

boolean isCanceller() :如果任务完成前被取消,则返回true。

boolean cancel(boolean mayInterruptRunning) :如果任务还没开始,执行cancel(...)方法将返回false;如果任务已经启动,执行cancel(true)方法将以中断执行此任务线程的方式来试图停止任务,如果停止成功,返回true;当任务已经启动,执行cancel(false)方法将不会对正在执行的任务线程产生影响(让线程正常执行到完成),此时返回false;当任务已经完成,执行cancel(...)方法将返回false。mayInterruptRunning参数表示是否中断执行中的线程。

通过方法分析我们也知道实际上Future提供了3种功能:(1)能够中断执行中的任务(2)判断任务是否执行完成(3)获取任务执行完成后额结果。

案例:

public class TestMain {

public static void main(String[] args) throws InterruptedException, ExecutionException {

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() {

 

}

 

@Override

public Integer call() throws Exception {

System.out.println("####AddNumberTask###call()");

Thread.sleep(5000);

return 5000;

}

 

}

 

Future模式

Future模式的核心在于:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑

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

 在多线程中经常举的一个例子就是:网络图片的下载,刚开始是通过模糊的图片来代替最后的图片,等下载图片的线程下载完图片后在替换。而在这个过程中可以做一些其他的事情。

 

案例:

public interface Data {

public abstract String getRequest();

}

 

 

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();

}

 

}

 

 

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;

}

 

 

public class FutureClient {

 

public Data request(String queryStr) {

FurureData furureData = new FurureData();

new Thread(new Runnable() {

 

@Override

public void run() {

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);

}

 

}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值