Notify、NotifyAll、Wait实现线程将的协作
线程间的协作
wait/notify和notifyAll 的使用场景(生产者/消费者)
消费者(等待方):
- 获取对象的锁
- 是否有商品,没有着调用wait方法进行等待
- 条件满足则执行业务逻辑
生产者(接收方):
- 获取对象的锁
- 补充商品(改变条件)
- 通知所有在该对象上等待的线程
代码实现:
public class WaitNotify {
private static boolean flag = true;
private static final Commodity lock = new Commodity();
public static void main(String[] args) throws Exception{
Thread consumer = new Thread(new Consumer());
Thread producer = new Thread(new Producer());
producer.start();
SleepUtils.second(1);
consumer.start();
}
private static class Consumer implements Runnable{
@Override
public void run() {
synchronized (lock){
while(true){
if(lock.count <= 0){
try {
System.out.println("货物消费完毕,等待补充 ... ");
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
lock.count -- ;
System.out.println("消费一件商品 ... ");
SleepUtils.second(1);
}
}
}
}
}
private static class Producer implements Runnable{
@Override
public void run() {
while(true){
synchronized (lock){
lock.count = 10 ;
System.out.println("补充商品");
lock.notifyAll();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
private static class Commodity{
private int count ;
}
}
/*
程序输出:
消费一件商品 ...
消费一件商品 ...
消费一件商品 ...
消费一件商品 ...
消费一件商品 ...
货物消费完毕,等待补充 ...
补充商品
消费一件商品 ...
消费一件商品 ...
消费一件商品 ...
消费一件商品 ...
消费一件商品 ...
货物消费完毕,等待补充 ...
*/
简单线程池的实现
public class ConnectionPool {
private LinkedList<Connection> pool = new LinkedList<>();
public ConnectionPool(int initialSize){
if(initialSize > 0){
for (int i = 0; i < initialSize; i++) {
pool.addLast(ConnectionDriver.createConnection());
}
}
}
public void releaseConnection(Connection connection){
if(connection != null){
synchronized (pool){
pool.addLast(connection);
// 当有线程归还连接时进行通知
// 目的是让消费者能感知到连接池中有连接
pool.notifyAll();
}
}
}
// 带超时时间的连接获取方式
public Connection fetchConnection(long mills) throws InterruptedException{
synchronized (pool){
// 不设置超时时间
if(mills <=0){
while(pool.isEmpty()){
pool.wait();
}
return pool.removeFirst();
}else{
long future = System.currentTimeMillis() + mills ;
long remain = mills ;
while(pool.isEmpty() && remain > 0){
pool.wait(remain);
//刷新剩余时间
remain = future - System.currentTimeMillis();
}
Connection result = null ;
//有可能 线程池中有线程 也有可能过了超时时间
if(!pool.isEmpty()){
result = pool.removeFirst();
}
return result;
}
}
}
}
自定义简单的线程池
public class DefaultThreadPool {
//最大工作线程数
private static final int MAX_WORKER_NUMBERS = 10;
//默认工作线数
private static final int DEFAULT_WORKER_NUMBER = 5 ;
//最小工作线程数
private static final int MIN_WORKER_NUMBERS = 1;
//任务列表,存储用户提交的任务信息
private final LinkedList<Job> jobs = new LinkedList<>();
//工作线程列表
private final LinkedList<Worker> workers = new LinkedList<>();
//工作线程数量
private int workerNum = DEFAULT_WORKER_NUMBER ;
public DefaultThreadPool(){
initializeWorker(MIN_WORKER_NUMBERS);
}
public DefaultThreadPool(int num){
initializeWorker(num);
}
/**
* 添加任务到任务队列,并且按序执行
* @param job
*/
public void execute(Job job){
if(job == null)
return ;
synchronized (jobs){
jobs.addLast(job);
// 通知worker 有任务进来了
jobs.notifyAll();
}
}
public void shutdown(){
for (Worker worker : workers){
worker.shutdown();
}
}
public void addWorker(int num){
if(num < 0){
throw new IllegalArgumentException("参数异常");
}
// 当前还能添加多少个worker
int maxRemain = MAX_WORKER_NUMBERS - workerNum ;
num = Math.min(num, maxRemain);
for (int i = 0; i < num; i++) {
Worker worker = new Worker();
workers.add(worker);
}
}
public void removeWorker(int num){
if(num > workerNum - MIN_WORKER_NUMBERS){
throw new IllegalArgumentException("参数异常");
}
int count = 0;
while(count < num){
Worker worker = workers.get(count);
if(workers.remove(worker)){
worker.shutdown();
count++;
}
}
workerNum -= num;
}
public void initializeWorker(int num){
num = Math.max(num,MIN_WORKER_NUMBERS);
for (int i = 0; i < num; i++) {
Worker worker = new Worker();
workers.add(worker);
}
}
// 用户提交的任务
interface Job{
void run();
}
// 工作线程
private class Worker implements Runnable{
private volatile boolean running = true;
/**
* 获取任务列表中的任务执行
*/
@Override
public void run() {
Job job = null ;
while(running){
synchronized (jobs){
// 任务列表为空,进行等待
while(jobs.isEmpty()){
try {
this.wait();
} catch (InterruptedException e) {
// 对中断进行响应
Thread.currentThread().interrupt();
return ;
}
}
// 任务队列中有任务
// 获取任务并且释放锁
job = jobs.removeFirst();
}
if(job != null){
//执行job方法
job.run();
}
}
}
public void shutdown(){
this.running = false;
}
}
}