并发包之Future:代码级控制超时时间

先谢Doug Lea。


使用场景:

最近在做webservice调用的时候,发现一个问题,对方的webservice接口很不稳定,所以在获取的数据时候经常要等待很久才能把数据全部拉回来,甚至有时候直接就抛异常了,这种阻塞很耗费时间,性能很低。针对这种情况,我需要将一定时间内没有返回结果的调用KILL掉,于是用到了并发包Future,实现并在生产环境运行良好。

============================================================

2015-07-13修改备注:

1、之前的代码存在executor没有关闭的异常;

2、对新来的朋友提个建议,频繁创建single线程池不是一个好建议。我之前的场景并发很低,看不出问题。随着现在接触的业务并发变得很大,根本不会这么写了,因为频繁的创建关闭线程会浪费很多资源。并发很小的情况,并且必须要控制超时时间的情况下可以试试。

很抱歉,本人阅历有限,希望没对读者造成影响。

============================================================

测试代码如下,自行体会:



package com.array7.concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class FutureTest {
	public static void main(String[] args) {
		String result = ControlTimeOut.call(new CallableImpl("OK"));
		System.out.println(result);
		result = ControlTimeOut.call(new CallableImpl("NO OK!"));
		System.out.println("result=" + result);
	}
}
class ControlTimeOut {
	@SuppressWarnings("unchecked")
	public static <T> T call(Callable<T> callable) {
		ExecutorService executor = Executors.newCachedThreadPool();
		Future<T> future = executor.submit(callable);
		try {
			T t = future.get(3000, TimeUnit.MILLISECONDS);
			executor.shutdwon();
			return t;
		} catch (InterruptedException e) {
			System.out.println("InterruptedException");
		} catch (ExecutionException e) {
			System.out.println("ExecutionException");
		} catch (TimeoutException e) {
			// TODO: coding here...
			System.out.println("TimeoutException");
		}
		return null;
	}
	
}

class CallableImpl implements Callable<String> {
	private static final String CORRECT_KEY = "OK";
	private String key = "";

	public CallableImpl(String key) {
		this.key = key;
	}
	
	public String call() {
		// TODO:真正的业务逻辑
		if (CORRECT_KEY.equals(this.getKey())) {
			return "SUCCESS";
		} else {
			try {
				Thread.sleep(5000);	// 阻塞。设置5秒超时,为了Future抛出TimeoutException
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "FAIL";
		}
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值