一、自定义线程池
1、定义拒绝策略-函数式接口
package ThreadPoolDemo20230911;
@FunctionalInterface
public interface RejectPolicy<T> {
void reject(MyBlockingQueue<T> blockingQueue, T task);
}
2、定义存放任务的队列
package ThreadPoolDemo20230911;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class MyBlockingQueue<T> {
private int capacity;
private Deque<T> queue = new ArrayDeque<>();
private ReentrantLock lock = new ReentrantLock();
private Condition fullCondition = lock.newCondition();
private Condition emptyCondition = lock.newCondition();
public MyBlockingQueue(int capacity) {
this.capacity = capacity;
}
public void put(T t) {
lock.lock();
try {
while (queue.size() == capacity) {
try {
System.out.println(Thread.currentThread().getName() + "等待加入队列。。" + t);
fullCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "加入队列。。" + t);
queue.addLast(t);
emptyCondition.signal();
} finally {
lock.unlock();
}
}
public T take() {
lock.lock();
try {
while (queue.size() <= 0) {
try {
emptyCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t = queue.pollFirst();
fullCondition.signal();
return t;
} finally {
lock.unlock();
}
}
public T poll(long timeout,TimeUnit unit){
lock.lock();
long nanos = unit.toNanos(timeout);
try {
while (queue.size() <= 0) {
try {
if (nanos<0){
return null;
}
nanos = emptyCondition.awaitNanos(nanos);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t = queue.pollFirst();
fullCondition.signal();
return t;
} finally {
lock.unlock();
}
}
public boolean offer(T t, long timeout, TimeUnit unit) {
lock.lock();
long nanos = unit.toNanos(timeout);
try {
while (queue.size() == capacity) {
try {
if (nanos < 0) {
return false;
}
System.out.println(Thread.currentThread().getName() + "等待加入队列。。" + t);
nanos = fullCondition.awaitNanos(nanos);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "加入队列。。" + t);
queue.addLast(t);
emptyCondition.signal();
return true;
} finally {
lock.unlock();
}
}
public void tryPut(RejectPolicy<T> rejectPolicy,T task){
lock.lock();
try {
if (queue.size() == capacity){
rejectPolicy.reject(this,task);
}else{
System.out.println("加入任务队列:" + task);
queue.addLast(task);
emptyCondition.signal();
}
}finally {
lock.unlock();
}
}
}
3、自定义线程池
package ThreadPoolDemo20230911;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
public class MyThreadPool {
private int coreSize;
private long timeout;
private TimeUnit timeUnit;
private RejectPolicy<Runnable> rejectPolicy;
private MyBlockingQueue<Runnable> blockingQueue;
private HashSet<Runnable> workers = new HashSet<>();
public MyThreadPool(int coreSize, long timeout, TimeUnit timeUnit, int queueCapacity, RejectPolicy<Runnable> rejectPolicy) {
this.coreSize = coreSize;
this.timeout = timeout;
this.timeUnit = timeUnit;
this.rejectPolicy = rejectPolicy;
blockingQueue = new MyBlockingQueue<Runnable>(queueCapacity);
}
public void execute(Runnable task) {
synchronized (workers) {
if (workers.size() >= coreSize) {
blockingQueue.tryPut(rejectPolicy,task);
} else {
Worker worker = new Worker(task);
System.out.println(Thread.currentThread().getName() + "新增worker:" + worker + ",task:" + task);
workers.add(worker);
worker.start();
}
}
}
class Worker extends Thread {
private Runnable task;
public Worker(Runnable task) {
this.task = task;
}
@Override
public void run() {
while (task != null || (task = blockingQueue.poll(timeout,timeUnit)) != null) {
try {
System.out.println(Thread.currentThread().getName() + "正在执行" + task);
task.run();
} finally {
task = null;
}
}
synchronized (workers) {
System.out.println(Thread.currentThread().getName() + "worker被移除:" + this.toString());
workers.remove(this);
}
}
}
}
4、测试
package ThreadPoolDemo20230911;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) {
MyThreadPool threadPool = new MyThreadPool(
1,
1000,
TimeUnit.MILLISECONDS,
2,
(queue, task) -> {
task.run();
}
);
for (int i = 0; i < 5; i++) {
int j = i;
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "执行任务:" + j);
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}
二、工作线程,让各自的任务都有自己的处理线程
package WorkerThreadDemo20230911;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class WorkerThread {
static final List<String> menu = Arrays.asList("m1","m2","m3","m4","m5");
static final Random RANDOM = new Random();
public static void main(String[] args) {
ExecutorService waitExecutorService = Executors.newFixedThreadPool(1);
ExecutorService cookExecutorService = Executors.newFixedThreadPool(1);
waitExecutorService.execute(()->{
System.out.println("order...");
Future<String> future = cookExecutorService.submit(() -> {
System.out.println("cooking...");
return cooking();
});
try {
System.out.println("serving "+future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
waitExecutorService.execute(()->{
System.out.println("order1...");
Future<String> future = cookExecutorService.submit(() -> {
System.out.println("cooking1...");
return cooking();
});
try {
System.out.println("serving1 "+future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
public static String cooking(){
return menu.get(RANDOM.nextInt(menu.size()));
}
}
三、任务类,将一个大任务分成多个小任务,最后将结果汇总
package ForkJoinDemo20230911;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class ForkJoinDemo {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool(4);
System.out.println(pool.invoke(new MyTask(1, 5)));
}
}
class MyTask extends RecursiveTask<Integer> {
private int begin;
private int end;
public MyTask(int begin, int end) {
this.begin = begin;
this.end = end;
}
@Override
protected Integer compute() {
if (begin == end) {
return begin;
}
if ((end - begin) == 1) {
return begin + end;
}
int mid = (begin + end) / 2;
MyTask taskLeft = new MyTask(begin, mid);
MyTask taskRight = new MyTask(mid + 1, end);
taskLeft.fork();
taskRight.fork();
System.out.println(taskLeft);
System.out.println(taskRight);
return taskLeft.join() + taskRight.join();
}
@Override
public String toString() {
return "MyTask{" +
"begin=" + begin +
", end=" + end +
'}';
}
}