当遇到代码中某句话或某个方法会卡死的状况,咱们该如何处理呢?
好比这段: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