Java concurrent programming JUC (four) blocking queue thread pool branch merge asynchronous callback

a blocking queue

The difference between stack and queue

insert image description here

Blocking queue BlockingQueue

insert image description here

  • 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

insert image description here

Blocking queue core method

insert image description here

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

insert image description here

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

insert image description here

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;
    }

insert image description here

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:
insert image description here

The underlying working principle of the thread pool

insert image description here

Alibaba Java Development Manual - Concurrency Control Notes

insert image description here

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;
        }));
    }

}

Guess you like

Origin blog.csdn.net/weixin_48244108/article/details/125342614