多线程编程步骤:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aBSlu9KL-1630340015888)(http://minio.riun.xyz/riun1/2021-08-26_10iuN4SVXbPv4rxa6y.jpg)]
线程间通信:
synchronized加锁,Object的wait睡觉 notifyAll唤醒(synchronized执行完自动释放锁)
Lock加锁,Condition的await睡觉 signalAll唤醒
用 notify()通知时,JVM 会随机唤醒某个等待的线程
Thread.sleep()不会释放锁,当前线程会等待,干巴巴的等待(比如一个线程执行到了synchronized的中sleep方法,就会拿着资源一直在这等);wait会主动释放锁,当前线程会等待。
悲观锁能解决线程中各种问题,但是缺点是不支持并发操作,每次只能有一个线程去执行。
乐观锁通过版本号控制多线程并发操作。check and set。
读写锁:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-baVgWEYS-1630340015890)(http://minio.riun.xyz/riun1/2021-08-30_11U4Z5RrycE5yRJ5MQ.jpg)]
写锁降级读锁
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LukBISqo-1630340015894)(http://minio.riun.xyz/riun1/2021-08-30_11U45eRYgW7Mg4sfl6.jpg)]
阻塞:在某些情况下挂起线程,一旦满足特定条件,被挂起的线程会自动被唤醒。
阻塞队列:一边往队列里面放数据,一边从队列里取数据,当队列满或取空了都会阻塞,而有空间或有数据后就又会自动触发来放数据,取数据。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQU9ZJCe-1630340015896)(http://minio.riun.xyz/riun1/2021-08-30_11Upw0aCNmDOUDQxuy.jpg)]
线程池:
//线程池方式创建
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);//一池多线程 核心线程数量n
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();//一池一线程 核心线程数量1
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();//可扩容线程 线程数不定 核心线程数量0
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);//定时线程 核心线程数量n
线程池架构:
线程池ThreadPoolExecutor核心构造参数:
线程池原理:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-neNlwKkA-1630340015908)(http://minio.riun.xyz/riun1/2021-08-30_11VyhYjo7pRTIbCRXz.jpg)]
注意:
1、执行execute或者submit时,才会创建线程。创建线程池时并没有创建线程
拒绝策略:
为什么不允许使用线程池工具类创建线程池?