From the development
A recent requirement encountered in the project was to implement a feature that could dynamically add scheduled tasks. At this point, some people might say simple, use Quartz, simple and rude. However, the Quartz framework is too heavy for small projects. Of course, some people would say that the JDK provides a Timer interface, which is fully adequate. However, the requirement of our project is completely multithreaded model, and the timer is single-threaded, so we chose JDK thread pool.
What is a thread pool
Java provides four thread pools through Executors: **newCachedThreadPool: ** Create a cacheable thread pool. If the thread pool length exceeds processing requirements, recycle idle threads. If no thread pool length can be recovered, create a thread. NewFixedThreadPool: Creates a fixed-length thread pool that controls the maximum number of concurrent threads, and the excess threads wait in the queue. NewScheduledThreadPool: Creates a thread pool of fixed length that supports scheduled and periodic task execution. NewSingleThreadExecutor: Creates a single-threaded thread pool that uses only one worker thread to execute tasks, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority).
NewScheduledThreadPool is used in the main project of the building, so that’s it.
Fetch of thread pool service
To obtain the thread pool service, use the singleton mode.
* @author wuhf * @date 2018/01/16 */ public class ThreadPoolUtils {private static ScheduledExecutorService executorService; privateThreadPoolUtils() {/ / manually create a thread pool. The executorService = new ScheduledThreadPoolExecutor (10, new BasicThreadFactory. Builder (). NamingPattern ("syncdata-schedule-pool-%d").daemon(true).build());
}
private static class PluginConfigHolder {
private final static ThreadPoolUtils INSTANCE = new ThreadPoolUtils();
}
public static ThreadPoolUtils getInstance() {
return PluginConfigHolder.INSTANCE;
}
public ScheduledExecutorService getThreadPool() {returnexecutorService; }}Copy the code
Interrupts a running thread code implementation
Without further ado, the code is as follows:
*/ Public class InterruptThread implements Runnable {private int num; public InterruptThread (int num){ this.num = num; } public static void main(String[] args) throws InterruptedException { Thread interruptThread = new Thread(new InterruptThread(1)); ScheduledFuture<? > t = ThreadPoolUtils. GetInstance (). GetThreadPool (). The scheduleAtFixedRate (interruptThread, 0, 2, TimeUnit. SECONDS); InterruptThread interruptThread1 = new InterruptThread(2); ThreadPoolUtils. GetInstance (). GetThreadPool (). The scheduleAtFixedRate (interruptThread1, 0, 2, TimeUnit. SECONDS); InterruptThread interruptThread2 = new InterruptThread(3); ThreadPoolUtils. GetInstance (). GetThreadPool (). The scheduleAtFixedRate (interruptThread2, 0, 2, TimeUnit. SECONDS); Thread.sleep(5000); InterruptThread t.ancel (interruptThread t.ancel (true);
while (true){
}
}
@Override
public void run() {
System.out.println("this is a thread"+ num); }}Copy the code
Record on pit
When using the following code, it occurred to me how to stop the thread running when the scheduled task needs to be stopped
ThreadPoolUtils. GetInstance (). GetThreadPool (). The scheduleAtFixedRate (interruptThread, 0, 2, TimeUnit. SECONDS);Copy the code
Since I had such a need, I googled it and couldn’t find anything on it. It was an in-depth analysis of Java thread pools. Or global variables, and did not find a satisfactory solution.
ScheduleAtFixedRate () {scheduleAtFixedRate () {scheduleAtFixedRate () {scheduleAtFixedRate () {scheduleAtFixedRate () {scheduleAtFixedRate ();
public ScheduledFuture<? > scheduleAtFixedRate(Runnablecommand,
long initialDelay,
long period,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (period <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(period));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
Copy the code
ScheduledFuture: ScheduledFuture: ScheduledFuture: ScheduledFuture
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled && removeOnCancel && heapIndex >= 0)
remove(this);
returncancelled; Public Boolean remove(Runnable task) {Boolean removed = workqueue.remove (task); tryTerminate(); // Incase SHUTDOWN and now empty
return removed;
}
Copy the code
Look up what super.cancel(mayInterruptIfRunning) is, and we see this,
Run public Boolean Cancel (Boolean mayInterruptIfRunning) {// Terminate the thread by calling its interrupt method.if(! (state == NEW && UNSAFE.compareAndSwapInt(this, stateOffset, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if(t ! = null) t.interrupt(); } finally { // final state UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); } } } finally { finishCompletion(); }return true;
}
Copy the code
All the problems are solved here.
So to sum up
There are always difficult solutions to be found in projects, and when Google is hard to find, it might be a good idea to check out the JDK source code. Finally, I would like to promote the blog of the landlord. The blog has been transferred to Tencent cloud and operated with several university friends, covering Java, Android and so on. If you are interested, please go to the blog of the landlord and his friends