[Thread Pool] Working Threads in Asynchronous Mode

1. Definition

  • 1. The worker thread is the worker thread
  • 2. Let limited worker threads handle infinite tasks asynchronously in turn
  • 3. It is a division of labor mode
  • 4. A typical implementation is a thread pool, which embodies the flyweight mode in the classic design mode
  • 5. Compared with another multi-threaded design pattern (Thread-Per-Message), a message is created to create a thread. This pattern will cause too many threads
  • 6. Different task types should use different thread pools, which can avoid starvation and improve efficiency

2. Hunger

2.1 Definition
  • 1. There will be starvation in the fixed-size thread pool
  • 2. There are two threads A and B in a thread pool, and the executed tasks include part 1 and part 2, and the execution of part 2 needs to depend on part 1 of the task
  • 3. Normal phenomenon: there is a task to be executed, thread B is blocked in executing part 2 of the task (because part 1 has not been executed yet), thread A executes part 1 of the task, thread A executes part 1 ends, and thread B executes the part of the task 2, then end, the overall task ends
  • 4. Starvation phenomenon: If there are two tasks to be executed, both thread A and thread B are executing part 2 of the two tasks, there is no thread processing part 1, and both thread A and thread B are in a blocked state, resulting in starvation
  • 5. It is not that threads hold each other's locks, but starvation caused by insufficient number of threads, not deadlock
2.2 Hunger code example
package com.learning.thread;

import lombok.extern.slf4j.Slf4j;

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

/**
 * 工作线程
 */
@Slf4j
public class WorkThread {
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        pool.execute(()->{
            log.info("处理点餐");
            Future<String> future = pool.submit(() -> {
                log.info("做菜");
                return "宫保鸡丁";
            });
            try {
                log.debug("上菜", future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        });
        pool.execute(()->{
            log.info("处理点餐");
            Future<String> future = pool.submit(() -> {
                log.info("做菜");
                return "土豆肉丝";
            });
            try {
                log.debug("上菜", future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        });
    }
}
2.3 Address hunger
  • 1. The starvation phenomenon is caused by insufficient threads. Adding new threads can solve it, but it is not a fundamental solution. If there are more tasks to be executed, more threads are needed to process them. If the number of threads is not enough, there will still be starvation produce
  • 2. Different task types need to use different thread pools
  • 3. Part 1 and part 2 of the task need to be processed with different thread pool types
2.4 Solve hunger code example
package com.learning.thread;

import lombok.extern.slf4j.Slf4j;

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

/**
 * 工作线程
 */
@Slf4j
public class WorkThread {
    public static void main(String[] args) {
        ExecutorService pool1 = Executors.newFixedThreadPool(1);
        ExecutorService pool2 = Executors.newFixedThreadPool(1);
        pool1.execute(()->{
            log.info("处理点餐");
            Future<String> future = pool2.submit(() -> {
                log.info("做菜");
                return "宫保鸡丁";
            });
            try {
                log.debug("上菜", future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        });
        pool1.execute(()->{
            log.info("处理点餐");
            Future<String> future = pool2.submit(() -> {
                log.info("做菜");
                return "土豆肉丝";
            });
            try {
                log.debug("上菜", future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        });
    }
}

Guess you like

Origin blog.csdn.net/qq_32088869/article/details/131851370