1. Background: A project was reconstructed to unify the previously scattered multithreading and scheduled task threads, so as to reduce the amount of code and improve the readability of code.
2, directly on the code – can be directly COPY using —————————-
ExecutorServiceFactory: ExecutorServiceFactory:
package com.aaa.bbb.ccc.ddd; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; /** * @author & @date: Public Class ExecutorServiceFactory {// Instantiate ExecutorServiceFactory private static ExecutorServiceFactory executorServiceFactory = new ExecutorServiceFactory(); Private ExecutorService ExecutorService; Private ExecutorServiceFactory() {} /** * @function: ExecutorServiceFactory */ public static ExecutorServiceFactory getInstance() {return ExecutorServiceFactory; } /** * @Function: Create a long thread pool - it can be arranged in a given delay running commands or periodically perform * / public ExecutorService createScheduledThreadPool () {/ / cpus int availableProcessors = Runtime.getRuntime().availableProcessors(); / / create the executorService = Executors. NewScheduledThreadPool (availableProcessors * 10, getThreadFactory ()); return executorService; } /** * @Function: Create a single-threaded Executor, that is, create a unique worker thread to execute a task. It will use a unique worker thread to execute the task, ensure that all tasks are executed in the specified order (FIFO, LIFO, priority) * Executor, and run the thread in an unbounded queue. (Note that if this single thread is terminated due to a failure during execution prior to closure, * a new thread will replace it to perform subsequent tasks if needed). Each task is guaranteed to be executed sequentially, * and that no more than one thread is active at any given time. Unlike the equivalent newFixedThreadPool(1) *, you are guaranteed to use another thread without reconfiguring the executable returned by this method. * / public ExecutorService createSingleThreadExecutor () {/ / create the ExecutorService = Executors.newSingleThreadExecutor(getThreadFactory()); return executorService; } /** * @function: Create a cacheable thread pool, with the flexibility to recycle idle threads if the pool is too long for processing, or to create new threads if none are available * For programs that perform many short-term asynchronous tasks, these thread pools generally improve program performance. Calling execute reuses previously constructed threads (if available). * If no existing thread is available, a new thread is created and added to the pool. Terminates and removes threads from the cache that have not been used for 60 seconds. * Therefore, thread pools that remain idle for a long time do not use any resources. Note that you can use the ThreadPoolExecutor * constructor to create thread pools with similar properties but different details (such as the timeout parameter). */ public ExecutorService createCachedThreadPool() {// Create ExecutorService = Executors.newCachedThreadPool(getThreadFactory()); return executorService; } /** * @function: creates a thread pool with a specified number of worker threads. Each time a task is submitted, a worker thread is created, and if the number of worker threads reaches the initial maximum of the thread pool, the submitted task is put into the pool queue. * Reusable thread pools with a fixed number of threads to run as shared unbounded queues. At any point, at most nThreads * threads will be in an active state to process the task. If the attached task is submitted while all threads are active, the attached task will wait in the queue until there are available threads. * If any thread terminates due to failure during execution prior to closure, a new thread will replace it to perform subsequent tasks (if needed). * Threads in the pool persist until a thread is explicitly closed. * / public ExecutorService createFixedThreadPool (int count) {/ / create the ExecutorService = Executors. NewFixedThreadPool (count, getThreadFactory()); return executorService; } /** * @Function: Private ThreadFactory getThreadFactory() {return new ThreadFactory() {// AtomicInteger is an Integer class that provides atomic operations, Add/subtract AtomicInteger sn = new AtomicInteger(); @ Override public Thread newThread (Runnable r) {/ / security manager SecurityManager s = System. GetSecurityManager (); // all threads belong to one ThreadGroup. = null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); Thread t = new Thread(group, r); T.setname (" Task thread - "+ sn.incrementandGet ()); return t; }}; }}Copy the code
Create a ExecutorProcessPool thread handling class:
package com.aaa.bbb.ccc.ddd; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; /** * @function: thread handler * @author & @date: Lin. Li - June 14, 2018 */ Public Class ExecutorProcessPool {// Private ExecutorService Executor; Private static ExecutorProcessPool pool = new ExecutorProcessPool(); /** * Creates a new instance of ExecutorProcessPool */ private ExecutorProcessPool() { executor = ExecutorServiceFactory.getInstance().createCachedThreadPool(); ExecutorProcessPool */ public static ExecutorProcessPool getInstance() {return pool; */ public void shutdown(){executor.shutdown(); */ public void shutdown(){executor.shutdown(); } /** * @function: submit task to thread pool, can receive thread return value - Future mode */ public Future<? > submit(Runnable task) { return executor.submit(task); } public Future<? > submit(Callable<? > task) { return executor.submit(task); } public void execute(Runnable task){executor.execute(task);} public void execute(Runnable task){execute(task); }}Copy the code
The core code is all there is to it, and the following is the test class:
package com.goldpac.ito.system.interceptor; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * @function: thread pool test class * @author & @date: ExecutorTest {public static void main(String[] args) {// Obtain an ExecutorProcessPool instance pool = ExecutorProcessPool.getInstance(); - for (int I = 0; i < 200; i++) { Future<? > future = pool.submit(new ExcuteTask1(i + "")); Try {// If the receiving thread returns a value, future.get() will block. Therefore, receiving the return value is not recommended for non-special cases. System.out.println(future.get()); } catch (Exception e) { e.printStackTrace(); }} // No return value. You can execute a task, but you cannot determine whether the task completed successfully. //execute(Runnable x); //for (int i = 0; i < 200; i++) { // pool.execute(new ExcuteTask2(i + "")); } // close the thread pool. Do not call this method if you need to run a thread pool for a long time. // When the listener exits, it is best to execute it. pool.shutdown(); } /** * static class ExcuteTask1 implements Callable<String> {private String taskName; public ExcuteTask1(String taskName) { this.taskName = taskName; } @ Override public String call () throws the Exception {try {/ / Java 6/7. The best way to sleep for TimeUnit MILLISECONDS. Sleep (100); Thread.sleep(100); / / random number less than 1000 MILLISECONDS, simulated business logic processing TimeUnit. MILLISECONDS. Sleep ((int) (Math. The random () * 1000)); } catch (Exception e) { e.printStackTrace(); } System. Out. Println (" -- -- -- -- -- -- -- -- -- -- -- -- -- here to execute the business logic, Callable TaskName = "+ TaskName +" -- -- -- -- -- -- -- -- -- -- -- -- -- "); Return "> > > > > > > > > > > > > thread return values, Callable TaskName =" + TaskName + "< < < < < < < < < < < < < <"; */ static class ExcuteTask2 implements Runnable {private String taskName; public ExcuteTask2(String taskName) { this.taskName = taskName; } @override public void run() {try {// random number within 1000 ms, Simulation of business logic to handle TimeUnit. MILLISECONDS. Sleep ((int) (Math. The random () * 1000)); } catch (Exception e) { e.printStackTrace(); } System. Out. Println (" -- -- -- -- -- -- -- -- -- -- -- -- -- here to execute the business logic, Runnable TaskName = "+ TaskName +" -- -- -- -- -- -- -- -- -- -- -- -- -- "); }}}Copy the code