【线程池】异步模式之工作线程

一、定义

  • 1.工作线程即worker thread
  • 2.让有限的工作线程来轮流异步处理无限多的任务
  • 3.是一种分工模式
  • 4.典型实现是线程池,体现了经典设计模式中的享元模式
  • 5.对比另一种多线程设计模式(Thread-Per-Message),来一条消息便创建一个线程,这种模式会造成线程数量过多
  • 6.不同任务类型应该使用不同的线程池,这样能够避免饥饿,提升效率

二、饥饿

2.1 定义
  • 1.固定大小线程池会有饥饿现象
  • 2.一个线程池中有两个线程A和B,执行的任务有部分1和部分2,执行部分2需要依赖于任务的部分1
  • 3.正常现象:有一个任务需要执行,线程B执行任务的部分2阻塞(因为部分1还未执行完),线程A执行任务的部分1,线程A执行部分1结束,线程B执行任务的部分2,然后结束,整体任务结束
  • 4.饥饿现象:如果有两个任务需要执行,线程A和线程B都在执行两个任务的部分2,没有线程处理部分1,而线程A和线程B都处于阻塞状态,而造成饥饿现象
  • 5.并不是线程互相持有对方的锁,而是线程数量不足造成的饥饿现象,并不是死锁
2.2 饥饿代码示例
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 解决饥饿
  • 1.饥饿现象是因为线程不足造成的,新增线程是可以解决,但不是根本解决方法,如果有更多的任务要执行,则需要更多的线程来处理,线程数量不够还是会有饥饿现象产生
  • 2.不同的任务类型需要使用不同的线程池
  • 3.任务的部分1和部分2需要用不同的线程池类型来处理
2.4 解决饥饿代码示例
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();
            }
        });
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32088869/article/details/131851370