java asynchronous - thread, thread pool

1. 4 ways to initialize threads in java

  1. Inherit Thread, rewrite the run method
  2. Implement the Runnable interface
  3. Implement Callable interface + FutureTask (can get thread return interface, can handle exceptions)
  4. Thread Pool

  • Either way, you need to use new Thread to open the thread

2. 4 Realization Cases

2.1. Inherit the Thread method

3. Implement the Runnable interface

2.2. Implement the Callable interface

  • Implement the Callable interface and specify the generic type
  • Override the call method
  • When using, pass the callable implementation class object when new FutureTask
  • Since the bottom layer of FutureTask uses the runnable interface, so the new Thread object can be passed in the FutureTask object

When the FutureTask object needs to obtain the returned data of the thread:

  • Obtain results by thread blocking and waiting: contrary to the original intention of multi-threading

2.3, thread pool

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author 线程池使用
 * @date 2023/7/7
 */
public class ExecutorsPool {
    /**
     * 在java JUC下,提供了一个类Executors,快速创建一个线程池
     *   下面创建一个固定数据为10的线程池
     */
    public static ExecutorService executors = Executors.newFixedThreadPool(10);

    //测试案例
    public static void main(String[] args) {
        System.out.println("主方法..................开始执行");
        
        //executors.submit(new Runnable() {
        //    @Override
        //    public void run() {
        //        
        //    }
        //})
        /** 下面是上面的lambda写法 */
        executors.submit(() -> {
            System.out.println("当前线程编号为:" + Thread.currentThread().getContextClassLoader());
            int a = 10 / 5;
            System.out.println("线程计算结果为:" + a);
        });
        System.out.println("主方法..................结束执行");
    }
}

The result is as follows:

Notice:

Executors.submit()与Executors.execute()区别:

  • The return type of the submit method is Future<T>, and the thread result can be obtained
  • The return type of the execute method is void, and the thread result cannot be obtained

3. Thread pool

3.1, the original creation method

  • ThreadPoolExecutor executor = new ThreadPoolExecutor();
  • Just pass the seven parameters of the thread
  • The bottom layer of ThreadPoolExecutor and Executors in 2.4 implements ExecutorService

3.2. Seven parameters of threads

<1> corePoolSize

Number of core threads:

  • After the thread pool is created, it will exist until the thread pool is destroyed.
  • After the thread pool is created, the number of threads that are ready, waiting to receive asynchronous tasks to execute

For example: corePoolSize = 5 After the thread is created, there are 5 threads in the thread pool Thread to process business at any time start()

<2>maximumPoolSize

Maximum number of threads:

  • Maximum number of threads, used to control resources
<3>heepAliverTime

Survival time:

  • The number of current is greater than the number of core threads, and when the idle threads exceed the survival time , release redundant idle threads
  • The idle thread here refers to: the thread business has been processed and is waiting for a new multi-thread business. At this time, the thread is idle.
  • Released threads: Since there are core threads, the released idle threads are: the number of current threads - the number of core threads
<4>TimeUnit unit

time-to-live unit

<5>BlockingQueue<Runnable> workQueue

Blocking queue:

  • If there are many multi-threaded tasks, the current redundant tasks will be placed in the queue
  • As long as a thread is idle, a new task will be taken from the queue for execution
<6>threadFactory

thread creation factory

<7>RejectedExecutionHandler handler

Processor: If the queue is full, refuse to execute the task according to the rejection policy we specified (saturation policy)

3.3 Cases

 Thread pool work order
  1. After the thread pool is created, the number of core core threads is ready to receive multi-threaded tasks
  2. When the core thread is full, it will put the incoming tasks into the blocking queue, and the idle core will go to the blocking queue to get the task execution by itself.
  3. When the blocking queue is full, a new thread is opened directly to execute the task, and the maximum can only be opened to the number specified by max
  4. When max is full, use the handler rejection strategy to reject the task
  5. After the execution of max is completed, if there are many idle threads, after the specified time keepAliveTime, release the redundant threads
interview case
  • How is a thread core 7; max 20; queue 50; 100 concurrently allocated?
  1. 7 concurrency will be executed immediately
  2. 50 will enter the queue
  3. Open 13 more for execution, here are 13 in the queue! (FIFO and LIFO, mainly depends on which queue is used)
  4. Use the rejection strategy for the remaining 30, such as: use the CallerRunsPolicy rejection strategy to allow the remaining concurrent synchronous execution

like:

import java.util.concurrent.*;

public class ThreadPoolTest {
    public static void main(String[] args) {
        System.out.println("线程池创建......");
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                7
                , 20
                , 10
                , TimeUnit.SECONDS
                , new LinkedBlockingDeque<>(50)
                , Executors.defaultThreadFactory()
                , new ThreadPoolExecutor.AbortPolicy()
        );
        //模拟100个并发
        for (int i = 0; i < 100; i++) {
            int num = i;
            executor.execute(()->{
                System.out.println(Thread.currentThread().getName() + "is executing:" + num);
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

result:

线程池创建......
pool-1-thread-1is executing:0
pool-1-thread-5is executing:4
pool-1-thread-7is executing:6
pool-1-thread-6is executing:5
pool-1-thread-3is executing:2
pool-1-thread-2is executing:1
pool-1-thread-4is executing:3
pool-1-thread-8is executing:57
pool-1-thread-9is executing:58
pool-1-thread-11is executing:60
pool-1-thread-10is executing:59
pool-1-thread-13is executing:62
pool-1-thread-12is executing:61
pool-1-thread-14is executing:63
pool-1-thread-17is executing:66
pool-1-thread-15is executing:64
pool-1-thread-16is executing:65
pool-1-thread-19is executing:68
pool-1-thread-18is executing:67
pool-1-thread-20is executing:69
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.shuizhu.helloworld.thread.ThreadPoolTest$$Lambda$1/1879492184@357246de rejected from java.util.concurrent.ThreadPoolExecutor@2a18f23c[Running, pool size = 20, active threads = 20, queued tasks = 50, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
    at com.shuizhu.helloworld.thread.ThreadPoolTest.main(ThreadPoolTest.java:20)
pool-1-thread-1is executing:7
pool-1-thread-16is executing:10
pool-1-thread-4is executing:11
pool-1-thread-14is executing:9
pool-1-thread-13is executing:8
pool-1-thread-19is executing:13
pool-1-thread-5is executing:12
pool-1-thread-15is executing:15
pool-1-thread-10is executing:17
pool-1-thread-8is executing:19
pool-1-thread-2is executing:22
pool-1-thread-17is executing:14
pool-1-thread-18is executing:25
pool-1-thread-20is executing:26
pool-1-thread-9is executing:24
pool-1-thread-7is executing:20
pool-1-thread-11is executing:23
pool-1-thread-6is executing:21
pool-1-thread-3is executing:18
pool-1-thread-12is executing:16
pool-1-thread-1is executing:27
pool-1-thread-14is executing:31
pool-1-thread-4is executing:30
pool-1-thread-16is executing:29
pool-1-thread-13is executing:28
pool-1-thread-20is executing:32
pool-1-thread-18is executing:37
pool-1-thread-17is executing:40
pool-1-thread-8is executing:36
pool-1-thread-15is executing:35
pool-1-thread-19is executing:33
pool-1-thread-5is executing:34
pool-1-thread-2is executing:39
pool-1-thread-10is executing:38
pool-1-thread-3is executing:41
pool-1-thread-11is executing:43
pool-1-thread-6is executing:42
pool-1-thread-9is executing:46
pool-1-thread-12is executing:44
pool-1-thread-7is executing:45 

rejection policy
  • DiscardOldestPolicy

Discard old tasks that have not yet been executed (the front of the queue is the oldest), and execute new tasks

  • CallerRunsPolicy

The redundant threads directly execute and call the run method, which is equivalent to synchronous execution

  • AbortPolicy (the default reject policy)

The new task is discarded directly, and an exception will be thrown

  • DiscardPolicy

The new task is discarded directly without throwing an exception

3.4, Executors create a thread pool

The above thread pool creation is the native way

You can also use Executors to create thread pools

1、Executors.newCachedThreadPool();
  • core core thread is 0, the maximum number of threads is Integer.MAX_VALUE
  • Create a thread pool that can cache threads (since the core thread is 0, the cache time is 60s), which can flexibly recycle idle threads

2、Executors.newFixedThreadPool(10);
  • Create a thread pool with a fixed number of threads
  • Core thread = maximum thread, so the thread is always alive
  • You can control the maximum number of concurrent threads, and the excess threads will wait in the queue

3、Executors.newScheduledThreadPool(10);
  • Create a fixed-length thread pool to support timing and periodic task execution
  • You can specify how long to execute after

4、Executors.newSingleThreadExecutor();
  •  Create a single-threaded thread pool that only uses a unique worker thread to execute tasks to ensure that all tasks are executed
  • Applicable scenario: In the distributed environment, to ensure the consistency of double writing, the same business needs to be left to the same server or the same thread for processing

Guess you like

Origin blog.csdn.net/weixin_42675423/article/details/131564775