- 1、JUC(java.util.concurrent) 是什么
- 2、Lock 接口
- 3、Java8 之lamda表达式复习
- 4、线程间通信
- 5、线程间定制化调用通信
- 6、NotSafeDemo
- 7、多线程锁
- 8、Callable接口
- 9、JUC 强大的辅助
- 10、ReentrantReadWriteLock 读写锁
- 11、BlockingQueueDemo 阻塞队列
- 12、ThreadPool线程池
- 1、线程池的参数
- 1.1 int corePoolSize : 线程池中的常驻核心 线程数
- 1.2 int maximumPoolSize : 线程池中能够容纳同时 执行的最大线程数,此值必须大于等于1
- 1.3 long keepAliveTime : 多余的空闲线程的存活时间,当前池中线程数量超过corePoolSize时,当空闲时间到达keepAliveTime时,多余线程会被销毁直到只剩余corePoolSize个线程为止
- 1.4 TimeUnit unit :keepAliveTime 的单位
- 1.5 BlockingQueue
workQueue : 任务队列,被提交但尚未被执行的任务 - 1.6 ThreadFactory threadFactory :表示生成线程池中工作线程的线程工厂,用于创建线程,一般默认即可。
- 1.7 RejectedExecutionHandler handler:拒绝策略,表示当队列 满了,并且工作线程大于等于线程池的最大线程数(maximumPoolSize) 时如何来拒绝请求执行的runnable 的策略
- 2、线程池的原理
- 3、线程用哪个?如何设置合理参数
- 1、线程池的参数
- 13、Java8之流式计算
- 14、分支合并框架
- 15、异步回调
1、JUC(java.util.concurrent) 是什么
在并发编程中使用的类
2、Lock 接口
3、Java8 之lamda表达式复习
4、线程间通信
5、线程间定制化调用通信
1、高内聚前提下,线程操作资源类
2、判断 、 干活 、 通知
3、多线程交互中,必须要防止多线程的虚假唤醒,也即(判断只用while,不能用if)
�

为什么使用lock
Lock8锁
6、NotSafeDemo
集合类是不安全的
ConcurrentModificationException
1、导致原因
2、解决方案
1)使用Vector
2) 使用 Collections 工具类
3)JUC 包中,CopyOnWriteArrayList
�
3、优化建议(同样的错误,不出现第2次)
7、多线程锁
8、Callable接口
9、JUC 强大的辅助
10、ReentrantReadWriteLock 读写锁
11、BlockingQueueDemo 阻塞队列
12、ThreadPool线程池
1、线程池的参数
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;}
1.1 int corePoolSize : 线程池中的常驻核心 线程数
1.2 int maximumPoolSize : 线程池中能够容纳同时 执行的最大线程数,此值必须大于等于1
1.3 long keepAliveTime : 多余的空闲线程的存活时间,当前池中线程数量超过corePoolSize时,当空闲时间到达keepAliveTime时,多余线程会被销毁直到只剩余corePoolSize个线程为止
1.4 TimeUnit unit :keepAliveTime 的单位
1.5 BlockingQueue workQueue : 任务队列,被提交但尚未被执行的任务
1.6 ThreadFactory threadFactory :表示生成线程池中工作线程的线程工厂,用于创建线程,一般默认即可。
1.7 RejectedExecutionHandler handler:拒绝策略,表示当队列 满了,并且工作线程大于等于线程池的最大线程数(maximumPoolSize) 时如何来拒绝请求执行的runnable 的策略
2、线程池的原理
1、在创建了线程池后,开始等待请求。
2、当调用execute()方法添加一个请求任务时,线程池会做出如下判断:
2.1如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务;
2.2如果正在运行的线程数量大于或等于corePoolSize,那么将这个任务放入队列;
2.3如果这个时候队列满了且正在运行的线程数量还小于maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;
2.4如果队列满了且正在运行的线程数量大于或等于maximumPoolSize,那么线程池会启动饱和拒绝策略来执行。
3、当一个线程完成任务时,它会从队列中取下一个任务来执行。
4、当一个线程无事可做超过一定的时间(keepAliveTime)时,线程会判断:
如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉。
所以线程池的所有任务完成后,它最终会收缩到corePoolSize的大小。
3、线程用哪个?如何设置合理参数
13、Java8之流式计算
14、分支合并框架
package com.wujing.juc.forkjoin;import java.util.concurrent.ExecutionException;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.ForkJoinTask;import java.util.concurrent.RecursiveTask;/*** @author liuJieXin* @version v1.0* @className: ForkJoinDemo* @description <p> ForkJoin 测试 </p>* @date 2022/5/24 22:33*/public class ForkJoinDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {int end = 1000000;MyTask myTask = new MyTask(1, end);long start = System.currentTimeMillis();ForkJoinPool forkJoinPool = new ForkJoinPool();ForkJoinTask<Integer> submit = forkJoinPool.submit(myTask);System.out.println(submit.get());forkJoinPool.shutdown();System.out.println(System.currentTimeMillis() - start);long start1 = System.currentTimeMillis();int result = 0;for (int i = 1; i <= end; i++) {result += i;}System.out.println(result);System.out.println(System.currentTimeMillis() - start1);}}class MyTask extends RecursiveTask<Integer>{private static final Integer ADJUST_VALUE = 10;private int begin;private int end;private int result;public MyTask(Integer begin, Integer end) {this.begin = begin;this.end = end;}@Overrideprotected Integer compute() {if((end - begin) <= ADJUST_VALUE){for (int i = begin ; i <= end; i++) {result = result + i;}}else {int middle = (end + begin) /2;MyTask myTask1 = new MyTask(begin, middle);MyTask myTask2 = new MyTask(middle+1, end);myTask1.fork();myTask2.fork();// System.out.println(myTask1.join());// System.out.println(myTask2.join());result = myTask1.join() + myTask2.join();}return result;}}
