當遇到代碼中某句話或某個方法會卡死的狀況,咱們該如何處理呢?
好比這段: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