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

相關文章
相關標籤/搜索