澳门皇家线上娱乐java使用默认线程池踩过的坑,java中通用的线程池实例代码

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

场景

四个调节器,五个调治职分,分别处理三个目录下的txt文件,有些调解职分应对有个别复杂难题的时候会不停尤其长的时刻,以至有平昔不通的恐怕。大家须求1个manager来治本这几个task,当以此task的上3回进行时间距离未来赶过多少个调整周期的时候,就向来停掉这一个线程,然后再重启它,保险三个目的目录下未有待管理的txt文件聚积。

问题

直接使用java暗中同意的线程池调治task1和task二.出于外部txt的种种不可控原因,导致task2线程阻塞。现象正是task1和线程池调治器都符合规律运行着,不过task2迟迟未有动作。

理所当然,找到实际的隔开原因并拓展针对消除是很关键的。不过,这种方法很大概并不可能一心、通透到底、周全的拍卖好全部未知情形。大家供给确认保障职务线程或许调解器的健壮性!

方案陈设

线程池调节器并未原生的指向被调整线程的政工运维境况实行监察管理的API。因为task2是阻塞在大家的作业逻辑里的,所以最棒的点子是写2个TaskManager,全体的职分线程在施行职务前整整到这些TaskManager这里来注册自身。那个TaskManager就承受对于每种本人管辖范围内的task进行实时全程监督!

背后的显要正是什么样管理抢先6个施行周期的task了。

方案如下:

●1旦发现那些task线程,立时暂停它,然后重新重启;

●一旦发掘这些task线程,直接将总体pool清空并截止,重新放入那八个task
——task分明的境况下】;

方案执行

停顿后重启

●Task实现类

class FileTask extends Thread { private long lastExecTime = 0; protected long interval = 10000; public long getLastExecTime() {     return lastExecTime; } public void setLastExecTime(long lastExecTime) {     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 = new CopyOnWriteArraySet<FileTask>(); ExecutorService pool = Executors.newCachedThreadPool(); public void registerCodeRunnable(FileTask process) { runners.add(process); } public TaskManager (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。为啥吧?其实那是一个很基础的主题材料,您应该不会像自身同1马虎。查看Thread.start()的注明,
有那样一段:

It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution.

科学,3个线程不可见运营一回。那么它是怎么决断的吗?

public synchronized void start() {         /**          * A zero status value corresponds to state "NEW".    0对应的是state NEW          */ 

if (threadStatus != 0) //要是还是不是NEW state,就直接抛出11分!


澳门皇家线上娱乐 1


) 场景
三个调节器,多个调治职务,分别管理五个目录下的txt文件,有些调治任务应对有个别复杂难题的时候会…

java中通用的线程池实例代码,java线程池实例

复制代码 代码如下:
package com.smart.frame.task.autoTask;

import java.util.Collection;
import java.util.Vector;

/**
 * 任务分发器
 */
public class TaskManage extends Thread
{
    protected Vector<Runnable> tasks = new
Vector<Runnable>();
    protected boolean running = false;
    protected boolean stopped = false;
    protected boolean paused = false;
    protected boolean killed = false;
    private ThreadPool pool;

    public TaskManage(ThreadPool pool)
    {
        this.pool = pool;
    }

    public void putTask(Runnable task)
    {
        tasks.add(task);
    }

    public void putTasks(Runnable[] tasks)
    {
        for (int i = 0; i < tasks.length; i++)
            this.tasks.add(tasks[i]);
    }

    public void putTasks(Collection<Runnable> tasks)
    {
        this.tasks.addAll(tasks);
    }

    protected Runnable popTask()
    {
        if (tasks.size() > 0) return (Runnable) tasks.remove(0);
        else return null;
    }

    public boolean isRunning()
    {
        return running;
    }

    public void stopTasks()
    {
        stopped = true;
    }

    public void stopTasksSync()
    {
        stopTasks();
        while (isRunning())
        {
            try
            {
                sleep(5);
            }
            catch (InterruptedException e)
            {
                TaskException.getResultMessage(e);
            }
        }
    }

    public void pauseTasks()
    {
        paused = true;
    }

    public void pauseTasksSync()
    {
        pauseTasks();
        while (isRunning())
        {
            try
            {
                sleep(5);
            }
            catch (InterruptedException e)
            {
                TaskException.getResultMessage(e);
            }
        }
    }

    public void kill()
    {
        if (!running) interrupt();
        else killed = true;
    }

    public void killSync()
    {
        kill();
        while (isAlive())
        {
            try
            {
                sleep(5);
            }
            catch (InterruptedException e)
            {
                TaskException.getResultMessage(e);
            }
        }
    }

    public synchronized void startTasks()
    {
        running = true;
        this.notify();
    }

    public synchronized void run()
    {
        try
        {
            while (true)
            {
                if (!running || tasks.size() == 0)
                {
                    pool.notifyForIdleThread();
                    this.wait();
                }
                else
                {
                    Runnable task;
                    while ((task = popTask()) != null)
                    {
                        task.run();
                        if (stopped)
                        {
                            stopped = false;
                            if (tasks.size() > 0)
                            {
                                tasks.clear();
                               
System.out.println(Thread.currentThread().getId() + “: Tasks are
stopped”);
                                break;
                            }
                        }
                        if (paused)
                        {
                            paused = false;
                            if (tasks.size() > 0)
                            {
                               
System.out.println(Thread.currentThread().getId() + “: Tasks are
paused”);
                                break;
                            }
                        }
                    }
                    running = false;
                }

                if (killed)
                {
                    killed = false;
                    break;
                }
            }
        }
        catch (InterruptedException e)
        {
            TaskException.getResultMessage(e);
            return;
        }
    }
}

复制代码 代码如下:
package com.smart.frame.task.autoTask;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

/**
 * 线程池
 */
public class ThreadPool
{
    protected int maxPoolSize = TaskConfig.maxPoolSize;
    protected int initPoolSize = TaskConfig.initPoolSize;
    protected Vector<TaskManage> threads = new
Vector<TaskManage>();
    protected boolean initialized = false;
    protected boolean hasIdleThread = false;

    public ThreadPool()
    {
        super();
    }

    public ThreadPool(int maxPoolSize, int initPoolSize)
    {
        this.maxPoolSize = maxPoolSize;
        this.initPoolSize = initPoolSize;
    }

    public void init()
    {
        initialized = true;
        for (int i = 0; i < initPoolSize; i++)
        {
            TaskManage thread = new TaskManage(this);
            thread.start();
            threads.add(thread);
        }
    }

    public void setMaxPoolSize(int maxPoolSize)
    {
        this.maxPoolSize = maxPoolSize;
        if (maxPoolSize < getPoolSize()) setPoolSize(maxPoolSize);
    }

    /**
     * 重设当前线程数
若需杀掉某线程,线程不会马上杀掉,而会等到线程中的事
     * 务管理完成但此方法会霎时从线程池中移除该线程,不会等待事务管理甘休
     */
    public void setPoolSize(int size)
    {
        if (!initialized)
        {
            initPoolSize = size;
            return;
        }
        else if (size > getPoolSize())
        {
            for (int i = getPoolSize(); i < size && i <
maxPoolSize; i++)
            {
                TaskManage thread = new TaskManage(this);
                thread.start();
                threads.add(thread);
            }
        }
        else if (size < getPoolSize())
        {
            while (getPoolSize() > size)
            {
                TaskManage th = (TaskManage) threads.remove(0);
                th.kill();
            }
        }
    }

    public int getPoolSize()
    {
        return threads.size();
    }

    protected void notifyForIdleThread()
    {
        hasIdleThread = true;
    }

    protected boolean waitForIdleThread()
    {
        hasIdleThread = false;
        while (!hasIdleThread && getPoolSize() >= maxPoolSize)
        {
            try
            {
                Thread.sleep(5);
            }
            catch (InterruptedException e)
            {
                TaskException.getResultMessage(e);
                return false;
            }
        }

        return true;
    }

    public synchronized TaskManage getIdleThread()
    {
        while (true)
        {
            for (Iterator<TaskManage> itr = threads.iterator();
itr.hasNext();)
            {
                TaskManage th = (TaskManage) itr.next();
                if (!th.isRunning()) return th;
            }

            if (getPoolSize() < maxPoolSize)
            {
                TaskManage thread = new TaskManage(this);
                thread.start();
                threads.add(thread);
                return thread;
            }

            if (waitForIdleThread() == false) return null;
        }
    }

    public void processTask(Runnable task)
    {
        TaskManage th = getIdleThread();
        if (th != null)
        {
            th.putTask(task);
            th.startTasks();
        }
    }

    public void processTasksInSingleThread(Runnable[] tasks)
    {
        TaskManage th = getIdleThread();
        if (th != null)
        {
            th.putTasks(tasks);
            th.startTasks();
        }
    }

    public void processTasksInSingleThread(Collection<Runnable>
tasks)
    {
        TaskManage th = getIdleThread();
        if (th != null)
        {
            th.putTasks(tasks);
            th.startTasks();
        }
    }

}

复制代码 代码如下:
package com.smart.frame.task.autoTask;

public class TopTask implements Runnable
{

    private ThreadPool pool;

    public TopTask()
    {
        super();
    }

    public TopTask(ThreadPool pool)
    {
        super();
        this.pool = pool;
    }

    @Override
    public void run()
    {
        init();
        start();
    }

    /**
     * 伊始化验证权限、参数之类
     */
    public void init()
    {

    }

    /**
     * 初始活动职务
     */
    public void start()
    {
        for (int i = 0; i < 10; i++)
        {
            pool.processTask(new BeginAuto());
        }
    }
}
/**
 * 实现类
 */
class BeginAuto implements Runnable
{
    @Override
    public void run()
    {
        System.out.println(Thread.currentThread().getId() +
“………………”);
    }

}

复制代码 代码如下: package com.smart.frame.task.autoTask; import
java.util.Collection; import java.util.Vector;…

补充表明:
概念:守护线程–也称“服务线程”,在未有用户线程可服务时会自动离开。
优先级:守护线程的优先级好低,用于为系统中的别的对象和线程提供劳务。
安装:通过setDaemon(true)来设置线程为“守护线程”;将1个用户线程设置为
守护线程的格局是在 线程对象创设 在此以前 用线程对象的setDaemon方法。
example:
垃圾回收线程正是1个卓越的医生和医护人员线程,当咱们的次序中不再有别的运营的
Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是
JVM上仅剩的线程时,垃圾回收线程会自行离开。它始终在低档其他情事中运作,用于
实时监督和保管类别中的可回收财富。
生命周期:守护进度(Daemon)是运行在后台的1种非常进度。它独立于决定终端并且
周期性地施行某种职务或等待管理某些发生的事件。也正是
说守护线程不依据于极端,然则依据于系统,与系统“同生共死”。那Java的照应线程是
如何体统的呢。当JVM中有着的线程都以照顾线程的时候,JVM就能够脱离了;如若还有三个
或上述的非守护线程则JVM不会脱离。

  1. class MyDaemon implements Runnable {  
  2.   public void run() {  
  3.   for (long i = 0; i < 9999999L; i++) {  
  4.   System.out.println(“后台线程第” + i + “次施行!”);  
  5.   try {  
  6.   Thread.sleep(7);  
  7.   } catch (InterruptedException e) {  
  8.   e.printStackTrace();  
  9.   }  
  10.   }  
  11.   }  
  12.   }  

 

观望了呢,把输入输出逻辑包装进守护线程多么的可怕,字符串并未写入钦定文件。原因也很简短,直到主线程完结,守护线程仍处在一秒的阻塞状态。今年主线程异常的快就运营完了,虚拟机退出,Daemon甘休服务,输出操作自然失利了。

  1. //代码清单StartCycleRunTask:容器监听器  
  2. package com.baobaotao.web;  
  3. import java.util.Date;  
  4. import java.util.Timer;  
  5. import java.util.TimerTask;  
  6. import javax.servlet.ServletContextEvent;  
  7. import javax.servlet.ServletContextListener;  
  8. public class StartCycleRunTask implements ServletContextListener …{  
  9.     private Timer timer;  
  10.     public void contextDestroyed(ServletContextEvent arg0) …{  
  11.         // 2该方法在Web容器关闭时举行  
  12.         System.out.println(“Web应用程序运维关闭…”);  
  13.     }  
  14.     public void contextInitialized(ServletContextEvent arg0) …{  
  15.          //贰在Web容器运维时自动实行该措施  
  16.         System.out.println(“Web应用程序运行…”);  
  17.         timer = new Timer();//二-一:创立一个Timer,Timer内部机动成立叁个背景线程  
  18.         TimerTask task = new SimpleTimerTask();  
  19.         timer.schedule(task, 1000L, 伍仟L); //2-贰:注册三个伍分钟运营2次的职分  
  20.     }  
  21. }  
  22. class SimpleTimerTask extends TimerTask …{//③任务  
  23.     private int count;  
  24.     public void run() …{  
  25.         System.out.println((++count)+”execute task…”+(new Date()));  
  26.     }  
  27. }  

[java] view
plain copy

[java] view
plain copy

咱俩能够通过退换清单StartCycleRunTask的代码,在contextDestroyed(ServletContext伊芙nt
arg0)中增多timer.cancel()代码,在Web容器关闭后手工业结束提姆er来甘休职责。

 

下边通过2个小例子来演示那个“奇怪”的场馆,大家由此ServletContextListener在Web容器运行时创造三个Timer并周期性地运维二个任务:
 

(一)
thread.setDaemon(true)必须在thread.start()此前设置,不然会跑出1个IllegalThreadStateException卓殊。你不能够把正在运作的正规线程设置为护理线程。
(二) 在Daemon线程中发出的新线程也是Daemon的。 
(三)
不要以为全数的行使都得以分配给Daemon来开始展览劳动,比如读写操作可能总括逻辑。 

1经当前JVM实例中尚存在任何二个非守护线程未有终结,守护线程就总体办事;唯有当最后三个非守护线程停止时,守护线程随着JVM一起结束职业。
Daemon的成效是为其它线程的周转提供方便人民群众服务,守护线程最特出的施用就是 GC
(垃圾回收器),它正是3个很尽职的守护者。

事实上选拔例子:

[java] view
plain copy

转到汤姆cat调控台,你将见到固然Web应用已经关闭,但提姆er任务还在一意孤行地试行照旧——舞台已经拆除,戏子继续演出: 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图