a blocking queue
The difference between stack and queue
Blocking queue BlockingQueue
- When the queue is empty, the operation of getting elements from the queue will be blocked
- When the queue is full, the operation of adding elements from the queue will be blocked
Blocking Queue Classification
Blocking queue core method
package new_course.chp4.queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* @author Created by Lin Weihong
* @date on 2022/6/17 9:37
*/
public class BlockingQueueDemo {
public static void main(String[] args) throws InterruptedException {
//创建阻塞队列
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
//第一组
System.out.println(blockingQueue.add("a")); //true
System.out.println(blockingQueue.add("b")); //true
System.out.println(blockingQueue.add("c")); //true
System.out.println(blockingQueue.element());//a
// System.out.println(blockingQueue.add("d")); //Exception in thread "main" java.lang.IllegalStateException: Queue full
System.out.println(blockingQueue.remove());//a
System.out.println(blockingQueue.remove());//b
System.out.println(blockingQueue.remove());//c
// System.out.println(blockingQueue.remove());//Exception in thread "main" java.util.NoSuchElementException
//第二组
System.out.println(blockingQueue.offer("a")); //true
System.out.println(blockingQueue.offer("b")); //true
System.out.println(blockingQueue.offer("c")); //true
System.out.println(blockingQueue.offer("ww")); //false,当队列满,offer不会报错,而add会报错
System.out.println(blockingQueue.poll());//a
System.out.println(blockingQueue.poll());//b
System.out.println(blockingQueue.poll());//c
System.out.println(blockingQueue.poll());//null 当队列空,poll不会报错,而remove会报错
//第三组
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
// blockingQueue.put("w");//阻塞,直到队列有位置
blockingQueue.take();
blockingQueue.take();
blockingQueue.take();
// blockingQueue.take();//阻塞,直到队列有元素
//第四组
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("w",3L, TimeUnit.SECONDS)); //超过时间没放进去自动退出
}
}
Two thread pool
Why use a thread pool
Declaration of three thread pools
package new_course.chp4.threadpool;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @author Created by Lin Weihong
* @date on 2022/6/17 11:06
*/
public class MyThreadPoolDemo {
public static void main(String[] args) {
//一个线程池,五个工作线程,类似一个银行有五个窗口受理点
//ExecutorService threadPool = Executors.newFixedThreadPool(5);
//一个线程池,一个工作线程,类似一个银行有一个窗口受理点
//ExecutorService threadPool = Executors.newSingleThreadExecutor();
//以上两种都不好,因为总有不满足的情况,最好的情况是要有扩容
//一个线程池,N个工作线程,类似一个银行有N个窗口受理点
ExecutorService threadPool = Executors.newCachedThreadPool();
try {
//模拟有10个顾客过来银行办理业务,目前池子里面有五个工作人员提供服务
for (int i = 1; i <= 10; i++) {
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "\t 办理了业务");
});
try {
TimeUnit.MILLISECONDS.sleep(8);} catch (InterruptedException e) {
e.printStackTrace(); }
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭线程池
threadPool.shutdown();
}
}
}
The underlying principle of ThreadPool
7 parameters of thread pool
Source code interpretation:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
corePoolSize: the number of resident core threads
For example, the bank has five windows from Monday to Friday, corePoolSize = 5, but the business is not so busy on Sunday, so only one window is opened, and corePoolSize = 1 at this time.
maximumPoolSize: the maximum number of threads that can be accommodated in the thread pool
The maximumPoolSize value must be >=1
keepAliveTime: the number of times to wait
unit: time unit
TimeUnit.SECONDS
workQueue: blocking queue
It is equivalent to going to the bank to handle business, the windows are full, and people need to be taken to the back living room, and the living room is equivalent to a blocking queue
threadFactory: thread factory
Generally use the default, which is equivalent to a brand
handler: rejection policy
Rejection strategy, when the worker thread > maximumPoolSize, how to reject the Runnable strategy for request execution
JDK's built-in rejection strategy:
The underlying working principle of the thread pool
Alibaba Java Development Manual - Concurrency Control Notes
three-branch merge
package new_course.chp4.forkjoin;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
/**
* @author Created by Lin Weihong
* @date on 2022/6/17 20:38
* <p>
* 分支合并框架
* 分组计算1+...+100
* ForkJoinPool
* ForkJoinTask
* RecursiveTask
*/
public class ForkJoinDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyTask myTask = new MyTask(0, 100);
ForkJoinPool threadPool = new ForkJoinPool();
//递交任务
ForkJoinTask<Integer> forkJoinTask = threadPool.submit(myTask);
System.out.println(forkJoinTask.get());
threadPool.shutdown();
}
}
class MyTask extends RecursiveTask<Integer> {
//10以内不要forkjoin
private static final Integer ADJUST_VALUE = 10;
private int begin;
private int end;
private int result;
public MyTask(int begin, int end) {
this.begin = begin;
this.end = end;
}
@Override
protected Integer compute() {
if ((end - begin) <= ADJUST_VALUE) {
for (int i = begin; i <= end; i++) {
result += i;
}
} else {
int middle = (end + begin) / 2;
//一个任务算一部分
MyTask task01 = new MyTask(begin, middle);
MyTask task02 = new MyTask(middle + 1, end);
task01.fork();//重复递归调用compute
task02.fork();
result = task01.join() + task02.join();
}
return result;
}
}
Four asynchronous callbacks
package new_course.chp4.completablefuture;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
/**
* @author Created by Lin Weihong
* @date on 2022/6/17 21:18
*/
public class CompletableFutureDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
System.out.println(Thread.currentThread().getName() + "没有返回 update mysql ok");
});
completableFuture.get();
CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "有返回, insert mysql ok");
return 1024;
});
integerCompletableFuture.whenComplete((t,u) -> {
System.out.println("*********t: " + t);
System.out.println("*********u: " + u);
}).exceptionally((throwable -> {
System.out.println("**************"+throwable);
return 4444;
}));
}
}