callable 代码超时设置

当遇到代码中某句话或某个方法会卡死的状况,咱们该如何处理呢?
好比这段:html

// 保存原文信息
try {
        	List<ContentSource> tempContents = new LinkedList<ContentSource>(contents);
        	StoreHelper helper = new StoreHelper(PropertiesUtil.hbaseIp, PropertiesUtil.hbasePort);
        	for (int i = 0; i < tempContents.size(); i++) {
        		ContentSource srcContent = tempContents.get(i);
        		Content destContent = convertContent(srcContent);
        		logger.info("源码入库HBase:第--" + i + "--条:企业名称:" + destContent.getName());
        		helper.save(destContent);  // 注意!这句可能会卡死
    	}
	        contents.clear();
} catch (Exception e) {
        	e.printStackTrace();
	        logger.info("企业html源码没有入库,请检查HBase是否正确!", e);
}

调save()的时候就有可能致使线程卡死,一直在等待,没有响应,也不报异常。
这种状况咱们能够用Callable接口来对这句话设置超时处理,将这句话包进去。像这样:java

public class DataManagerHbaseHelper implements Callable<String> {
	private Content content;
	private StoreHelper helper;

	public Content getContent() {
		return content;
	}

	public void setContent(Content content) {
		this.content = content;
	}

	public StoreHelper getHelper() {
		return helper;
	}

	public void setHelper(StoreHelper helper) {
		this.helper = helper;
	}

	@Override
	public String call() throws Exception {
		helper.save(content);
		return "true";
	}
}

咱们把     helper.save(destContent);  这句须要的两个对象封到新的DataManagerHbaseHelper里面,以保证不改变原来代码,只检测超时。而后在call()方法中调用这句话。 在原始类中使用这个类来调用这句话并设置超时参数以下:ide

// 保存原文信息
			try {
				List<ContentSource> tempContents = new LinkedList<ContentSource>(contents);
				StoreHelper helper = new StoreHelper(PropertiesUtil.hbaseIp, PropertiesUtil.hbasePort);
				for (int i = 0; i < tempContents.size(); i++) {
					ContentSource srcContent = tempContents.get(i);
					Content destContent = convertContent(srcContent);
					logger.info("源码入库HBase:第--" + i + "--条:企业名称:" + destContent.getName());
		
    // ☆重点在这里
					//防止Hbase异常中止形成的存储线程中止
					DataManagerHbaseHelper dmh = new DataManagerHbaseHelper();
					dmh.setContent(destContent);
					dmh.setHelper(helper);
					ExecutorService exec = Executors.newCachedThreadPool();
					Future<String> submit = exec.submit(dmh);
					exec.shutdown();
					String reCode = submit.get(30000, TimeUnit.MILLISECONDS); // 第一个参数设置超时时长,此处我设置为3s
					if(reCode.equals("true")){
						logger.info("存储hbase成功");
					}
				}
				contents.clear();
			}catch (InterruptedException e){
				e.printStackTrace();
				logger.info("Hbase存储程序阻塞,请检查HBase是否正常!", e);
			}
			catch (ExecutionException e){
				e.printStackTrace();
				logger.info("Hbase存储程序阻塞,请检查HBase是否正常!", e);
			}
			catch (TimeoutException e){
				e.printStackTrace();
				logger.info("Hbase存储程序阻塞,请检查HBase是否正常!", e);
			}
			catch (Exception e) {
				e.printStackTrace();
				logger.info("企业html源码没有入库,请检查HBase是否正确!", e);
			}

这样就能够控制这一句话超时时长了,时长能够本身定义,若是过长就会报TimeoutException。this

相关文章
相关标签/搜索