一、定义
- 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();
}
});
}
}