云智慧(北京)科技有限公司 陈鑫
Restart thread pool
TaskManager
public class TaskManager implements Runnable {
.....
Public TaskManager (setrunners) {
Super ();
This.runners = runners;
Executetasks (runners);
}
Private Voidexecutetasks (set<filetask> runners) {for (Filetask task:runners) {pool.execute (Task); System.out.println (Task.getclass (). Getsimplename () + "has beenstarted"); }} @Overridepublic void Run () {while (! Thread.CurrentThread (). isinterrupted ()) {try {long current = System.currenttimemillis (); for (Filetask wrapper:runners) {if (Wrapper.getlastexectime ()! = 0 && Current-wrapper.getlastexe CTime () > Wrapper.getinterval () * 5 * 1000) {//start forgetting to multiply the wrapper.interrupt (); if (wrapper.getfiles () = null) {for (File file:wrapper.getFiles ()) {fi Le.delete (); }} System.out.println ("Going to shutdown Thethread pool"); list<runnable> Shutdownnow = Pool.shutdownnow (); Without waiting for the task in the current pool to run, close the thread pool for (Runnable Run:shutdOwnnow) {System.out.println (run + "goingto be Shutdown"); } while (Pool.awaittermination (1, timeunit.seconds)) {System.out.println ("the THR Eadpool has been shutdown "+ new Date ()); Executetasks (runners);//re-executing thread.sleep (200); }}}} catch (Exception E1) {e1.printstacktrace (); } try {Thread.Sleep (500); } catch (Interruptedexception e) {}}}public static void Main (string[] args) {set<filetask> tasks =new Hashset<filetask> (); Filetask task = Newfiletask (); Task.setinterval (1); Task.setname ("task-1"); Tasks.add (Task); Filetask Task1 = Newfiletask (); Task1.setinterval (2); Task.setname ("Task-2"); Tasks.add (TASK1); TaskManager Codemanager = new TaskManager (tasks); Newthread (Codemanager). Start ();}
}
Success! Stop all the workers in the entire threadpoolexector and then rejoin the queue with the two tasks to be performed (note that this is not empty, just stop). While this can be done in a timely manner, a fatal disadvantage is that there is no way to re-perform these tasks if you do not have a clear idea of the task that Threadpoolexecutor will execute.
Custom thread pool
Stop delving into other people's stuff! We can write our own threadpoolexecutor, as long as we expose the worker to it. It's not back to the start problem here, yes, even if we can interrupt the thread directly, but we can't start it again. So clone a same thread line?
Thread
@Override
Protectedobject Clone () throws clonenotsupportedexception{
Throw Newclonenotsupportedexception ();
}
The answer is obvious: the thread does not support clone. We need to re-run the new thread again. In fact, we just need to replace the runnable in the original worker with our own task, and then let the access rights be properly released. Also, let our customthreadpoolexecutor inherit thread because it needs to monitor the running state of thread in all of its workers at regular intervals.
Customthreadpoolexecutor
public class Customthreadpoolexecutor Extendsthreadpoolexecutor implements Runnable {
Public voidexecute (Testask command) {
....//change the execution interface to receive our business class
}
...
...
Private Final Class Worker
Extends Abstractqueuedsynchronizer
Implements Runnable
{
...
Testask Firsttask; Change Runnable to our business class for easy viewing status
...
Worker (Testask firsttask) {
...//change the initialization parameter to our business class
}
}
Public staticvoid Main (string[] args) {
Customthreadpoolexecutor pool = new Customthreadpoolexecutor (0, Integer.max_value,
60L, Timeunit.seconds,
Newsynchronousqueue ());
Testasktask = new Testask(); task.setInterval(1); pool.execute(task); Testasktask1 = new Testask(); task1.setInterval(2); pool.execute(task1); newThread(pool).start();}@Overridepublic voidrun() { while(!Thread.currentThread().isInterrupted()) { try { long current = System.currentTimeMillis(); Set<Testask> toReExecute = new HashSet<Testask>(); System.out.println("\t number is " + number); for(Worker wrapper : workers) { Testask tt = wrapper.firstTask; if (tt != null) { if (current - tt.getLastExecTime() > tt.getInterval() * 5 * 1000) {
Wrapper.interruptifstarted ();
Remove (TT);
if (tt.getfiles () = null) {
for (File file:tt.getFiles ()) {
File.delete ();
}
}
System.out.println ("THread is timeout:" + TT + "" + New Date ());
Toreexecute.add (TT);
}
}
}
if (toreexecute.size () > 0) {
Mainlock.lock ();
try {
for (Testask tt:toreexecute) {
Execute (TT),//execute this task again
}
} finally {
Mainlock.unlock ();
}
}
} catch (Exception E1) {
System.out.println ("Error happens when we trying to interrupt andrestart a Code task ");
}
try {
Thread.Sleep (500);
} catch (Interruptedexception e) {
}
}
}
}
Testask
class Testask implements Runnable {
.....
@Overridepublic voidrun() { while(!Thread.currentThread().isInterrupted()) { lastExecTime = System.currentTimeMillis(); System.out.println(Thread.currentThread().getName() + " is running-> " + new Date()); try { CustomThreadPoolExecutor.number++; Thread.sleep(getInterval() * 6 * 1000); System.out.println(Thread.currentThread().getName() + " aftersleep"); } catch(InterruptedException e) {
Thread.CurrentThread (). interrupt ();
System.out.println ("interruptedexception happens");
}
}
System.out.println ("Going to die");
}
}
Final Solution
In summary, the most secure is the use of JDK threadpoolexecutor, if you need to control the task in the pool at any time, you can consider a comprehensive update, all aspects, 360 degrees without dead ends of the custom thread pool is certainly the best solution, However, it is important to pay attention to the processing of shared objects, and properly handle the methods of concurrent access to shared objects.
In view of our scenario, because of the time is tight, and need to understand the task is not many, temporarily select the all re-updated policy. After the line, take the time to customize the Threadpoolexecutor to fix, and then update up!
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Java uses the default thread pool to step on the pit (c)