java使用默认线程池踩过的坑(一)

原创 2015年07月08日 10:27:19

云智慧(北京)科技有限公司 陈鑫
场景
一个调度器,两个调度任务,分别处理两个目录下的txt文件,某个调度任务应对某些复杂问题的时候会持续特别长的时间,甚至有一直阻塞的可能。我们需要一个manager来管理这些task,当这个task的上一次执行时间距离现在超过5个调度周期的时候,就直接停掉这个线程,然后再重启它,保证两个目标目录下没有待处理的txt文件堆积。

无

问题
直接使用java默认的线程池调度task1和task2.由于外部txt的种种不可控原因,导致task2线程阻塞。现象就是task1和线程池调度器都正常运行着,但是task2迟迟没有动作。
当然,找到具体的阻塞原因并进行针对性解决是很重要的。但是,这种措施很可能并不能完全、彻底、全面的处理好所有未知情况。我们需要保证任务线程或者调度器的健壮性!
方案计划
线程池调度器并没有原生的针对被调度线程的业务运行状态进行监控处理的API。因为task2是阻塞在我们的业务逻辑里的,所以最好的方式是写一个TaskManager,所有的任务线程在执行任务前全部到这个TaskManager这里来注册自己。这个TaskManager就负责对于每个自己管辖范围内的task进行实时全程监控!

无
后面的重点就是如何处理超过5个执行周期的task了。
方案如下:
一旦发现这个task线程,立即中止它,然后再次重启;
一旦发现这个task线程,直接将整个pool清空并停止,重新放入这两个task ——【task明确的情况下】;
方案实施
中止后重启
Task实现类
classFileTask extends Thread {
private long lastExecTime = 0;
protected long interval = 10000;

public long getLastExecTime() {
    returnlastExecTime;
}

public void setLastExecTime(longlastExecTime) {
    this.lastExecTime =lastExecTime;
}

public long getInterval() {
    return interval;
}

public void setInterval(long interval) {
    this.interval = interval;
}

public File[] getFiles() {
    return null;
}

@Override
public void run() {
    while(!Thread.currentThread().isInterrupted()) {
        lastExecTime = System.currentTimeMillis();
       System.out.println(Thread.currentThread().getName() + " is running ->" + new Date());
        try {
           Thread.sleep(getInterval() * 6 * 1000);
        } catch(InterruptedException e) {
       Thread.currentThread().interrupt();
           e.printStackTrace();    // 当线程池shutdown之后,这里就会抛出exception了
        }
    }
}

}
TaskManager
public class TaskManager implements Runnable {
private final static Log logger = LogFactory.getLog(TaskManager.class);

public Set<FileTask> runners = newCopyOnWriteArraySet<FileTask>();

ExecutorService pool =Executors.newCachedThreadPool();

public voidregisterCodeRunnable(FileTask process) {
runners.add(process);
}

publicTaskManager (Set<FileTask>runners) {
    this.runners = runners;
}

@Override
public void run() {
    while(!Thread.currentThread().isInterrupted()) {
        try {
           long current = System.currentTimeMillis();
           for (FileTask wrapper : runners) {
               if (current - wrapper.getLastExecTime() >wrapper.getInterval()* 5) {
                   wrapper.interrupt();
                   for (File file : wrapper.getFiles()) {
                       file.delete();
                   }
                wrapper.start();  
               }
            }
        } catch(Exception e1) {
           logger.error("Error happens when we trying to interrupt and restart a task");
           ExceptionCollector.registerException(e1);
        }
        try {
           Thread.sleep(500);
        } catch(InterruptedException e) {
        }
    }
}

}
这段代码会报错java.lang.Thread IllegalThreadStateException。为什么呢?其实这是一个很基础的问题,您应该不会像我一样马虎。查看Thread.start()的注释, 有这样一段:
It is never legal to start a thread more thanonce. In particular, a thread may not be restarted once it has completedexecution.

那些年我踩过的坑——Java

Java基础许久没写过程序,看看基础,避免坑爹 -复用构造器:只能在构造函数第一行调用其他构造函数,且只能调用一个 -接口适合用来实现mixin(将一个类变量完全复制到另一个类中) -类被loa...
  • pouloghost
  • pouloghost
  • 2015年07月10日 14:03
  • 602

致Android-那些年,我们一起踩过的坑

大爷的,从搞android至今,踩过的坑倒是不少,MD,要是同一个坑,踩一次也就算了,踩两次、多次那就显得狠low了…记录那些年,希望跟我踩同一个坑的同胞们一些帮助(主要是怕自己踩同一个坑,哈哈~~)...
  • yiluyoufeng
  • yiluyoufeng
  • 2016年06月18日 23:29
  • 581

前端总结:踩过的坑以及一些冷知识

主要是指css样式这一块。1、行内元素(比如img)默认会在末尾留白,无法去除。只能通过display:block;让其以块级元素进行显示。...
  • linysuccess
  • linysuccess
  • 2016年12月02日 10:56
  • 558

学习java踩过的那些坑

1、使用spring-mvc,页面一直无法跳到controller层,页面一直返回404。 原因,pom文件中少了commons-loging依赖。 2、mybatis自动注解,controlle...
  • SilenceCarrot
  • SilenceCarrot
  • 2016年12月26日 13:59
  • 529

VUE 使用中踩过的坑

(点击上方公众号,可快速关注)作者: Xguolianghttps://segmentfault.com/a/1190000013008420前言vue如今可谓是一匹黑马,github star数已居...
  • VhWfR2u02Q
  • VhWfR2u02Q
  • 2018年02月03日 00:00
  • 73

架构真经 | 那些年,我们踩过的缓存坑

在码农的世界里,一直以来都有一个信仰:只要应用使用了缓存,性能就会翻倍;用上缓存的应用就像是打通任督二脉的武林高手,内力生生不息。但是今天我想跟各位猿类朋友聊一聊自己在使用缓存时遇到的那些坑,这里主要...
  • qq_35246620
  • qq_35246620
  • 2017年05月05日 12:27
  • 2128

Java 开发中如何正确踩坑

动力节点 2017-05-31 09:06 官方微信:动力节点Java学院 为什么说一个好的员工能顶 100 个普通员工 我们的做法是,要用最好的人。我一直都认为研发本身是很有创造性的,如果人不放...
  • u011277123
  • u011277123
  • 2017年06月01日 21:39
  • 248

spring cloud 前人踩过的坑

1.zuul路由cookie消失 2.zuul跳转的服务重定向访问地址暴露
  • on_the_way_the_way
  • on_the_way_the_way
  • 2017年11月09日 19:34
  • 108

前端开发所踩过的坑

本文摘要来自摩拜前端团队 yingye ,如有不对地方请指正本文主要分享构建和开发中遇到的坑:比如预编译的支持、浏览器环境的 window 对象支持以及 ENV 的配置等等欢迎关注本系列,留言分享 s...
  • bjweimengshu
  • bjweimengshu
  • 2018年01月13日 00:00
  • 152

Redis上踩过的一些坑-美团

上上周和同事(龙哥)参加了360组织的互联网技术训练营第三期,美团网的DBA负责人侯军伟给大家介绍了美团网在redis上踩得一些坑,讲的都是干货和坑。     分为5个部分:    一、周期性...
  • chenleixing
  • chenleixing
  • 2016年01月17日 01:08
  • 21247
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java使用默认线程池踩过的坑(一)
举报原因:
原因补充:

(最多只允许输入30个字)