package com.koala.learn.charter4;

/**
* @Description TODO
* @Date 2022/2/28 0:04
* @Created by koala
*/

public class Start3 {
public static void main(String[] args) {
DefaultThreadPool<HouseWork> pool = new DefaultThreadPool<>(2);
pool.execute(new HouseWork(1000L,"dinner"));
pool.execute(new HouseWork(1000L,"clear"));
pool.execute(new HouseWork(1000L,"dish"));
pool.execute(new HouseWork(1000L,"close window"));
}
}
package com.koala.learn.charter4;

/**
* @Description TODO
* @Date 2022/2/27 21:25
* @Created by koala
*/

public interface ThreadPool<Job extends Runnable> {
// 执行一个工作
void execute(Job job);

void shutdown();

void addWorker(int num);

void removeWorker(int num);

int getJobSize();
}
package com.koala.learn.charter4;

import lombok.SneakyThrows;

/**
* @Description TODO
* @Date 2022/2/28 0:05
* @Created by koala
*/

public class HouseWork implements Runnable{

private Long time;

private String msg;

public HouseWork(Long time, String msg) {
this.time = time;
this.msg = msg;
}

@SneakyThrows
@Override
public void run() {
Thread.sleep(time);
System.out.println("I will do " + msg + " it will waste " + time + " second");
}
}
package com.koala.learn.charter4;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

/**
* @Description TODO
* @Date 2022/2/27 21:29
* @Created by koala
*/

public class DefaultThreadPool<Job extends Runnable> implements ThreadPool<Job> {

// 最大的工作人数
public static final int MAX_WORKER_NUMBERS = 10;

public static final int DEFAULT_WORKER_NUMBERS = 5;

public static final int MIN_WORKER_NUMBERS = 1;

private AtomicLong threadNum = new AtomicLong();

private int workNum = DEFAULT_WORKER_NUMBERS;

private final LinkedList<Job> jobs = new LinkedList<>();

private final List<Worker> workers = Collections.synchronizedList(new ArrayList<Worker>());


private void initWorkers(int num){
for(int i = 0;i < num;i++){
Worker worker = new Worker();
workers.add(worker);
Thread thread = new Thread(worker,"Thread-" + threadNum.incrementAndGet());
thread.start();
}
}

public DefaultThreadPool(int num){
initWorkers(num);
}

@Override
public void execute(Job job) {
if(job!=null){
synchronized (jobs){
jobs.addLast(job);
jobs.notifyAll();
}
}
}

@Override
public void shutdown() {
for (Worker worker:workers){
worker.shutdown();
}
}

@Override
public void addWorker(int num) {
synchronized (jobs){
if(num+this.workNum > MAX_WORKER_NUMBERS){
num = MAX_WORKER_NUMBERS-workNum;
}
initWorkers(num);
this.workNum += num;
}
}

@Override
public void removeWorker(int num) {
synchronized (jobs){
if(num > workNum){
throw new IllegalArgumentException("beyond worknum");
}
int count = 0;
while(count < num){
Worker worker = workers.get(count);
if(workers.remove(worker)){
worker.shutdown();
count++;
}
}
this.workNum -= count;
}
}

@Override
public int getJobSize() {
return jobs.size();
}

class Worker implements Runnable{
private volatile boolean running = true;

@Override
public void run() {
while (running){
Job job = null;
synchronized (jobs){
while(jobs.isEmpty()){
try {
jobs.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
job = jobs.removeFirst();
}
if(job != null){
job.run();
}

}
}
public void shutdown(){
running = false;
}

}
}