JUC的学习与应用(是对文章的补充)
sleep和wait的区别
(两者都须要捕捉异样,这个异样不是重点)
1、每个对象都有一个锁来管制同步拜访,Synchronized关键字能够和对象的锁交互,来实现同步办法或同步块。sleep()办法正在执行的线程被动让出CPU(而后CPU就能够去执行其余工作),在sleep指定工夫后CPU再回到该线程持续往下执行(留神:sleep办法只让出了CPU,而并不会开释同步资源锁!!!);wait()办法则是指以后线程让本人临时让步出同步资源锁,以便其余正在期待该资源的线程失去该资源进而运行,只有调用了notify()办法,之前调用wait()的线程才会解除wait状态,能够去参加竞争同步资源锁,进而失去执行。(留神:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权力从新参加线程的调度);
2、sleep()办法能够在任何中央应用;wait()办法则只能在同步办法或同步块中应用(否则执行的时候就会报错java.lang.IllegalMonitorStateException
)详情能够参考这个博客;
3、sleep()是线程线程类(Thread)的办法,调用会暂停此线程指定的工夫,但监控仍然放弃,不会开释对象锁,到工夫主动复原;wait()是Object的办法,调用会放弃对象锁,进入期待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次取得对象锁才会进入运行状态;
synchronized 和 lock
lock锁的几种机制上面举例具体阐明这四种办法的应用:如果线程A和线程B应用同一个锁LOCK,此时线程A首先获取到锁LOCK.lock(),并且始终持有不开释。如果此时B要去获取锁,有四种形式:
①LOCK.lock(): 此形式会始终处于期待中,即便调用B.interrupt()也不能中断,除非线程A调用LOCK.unlock()开释锁。②LOCK.lockInterruptibly(): 此形式会期待,但当调用B.interrupt()会被中断期待,并抛出InterruptedException异样,否则会与lock()一样始终处于期待中,直到线程A开释锁。
③LOCK.tryLock(): 该处不会期待,获取不到锁并间接返回false,去执行上面的逻辑。
④LOCK.tryLock(10, TimeUnit.SECONDS):该处会在10秒工夫内处于期待中,但当调用B.interrupt()会被中断期待,并抛出InterruptedException。10秒工夫内如果线程A开释锁,会获取到锁并返回true,否则10秒过后会获取不到锁并返回false,去执行上面的逻辑。
两者比照
- Synchronized 内置的Java关键字, Lock 是一个Java类
- Synchronized 无奈判断获取锁的状态,Lock 能够判断是否获取到了锁
- Synchronized 会主动开释锁,lock 必须要手动开释锁!如果不开释锁,死锁
- Synchronized 线程 1(取得锁,阻塞)、线程2(期待,傻傻的等);Lock锁就不肯定会期待下
去; - Synchronized 可重入锁,不能够中断的,非偏心;Lock ,可重入锁,能够 判断锁,非偏心(能够
本人设置); - Synchronized 适宜锁大量的代码同步问题,Lock 适宜锁大量的同步代码!
生产者消费者问题
传统wait和notify带来的虚伪唤醒问题
参考虚伪唤醒,也就是说在while中,被唤醒的时候是从wait的中央开始,这样就会再做一次判断,而if就间接走上面的逻辑,不会二次判断。参考案例
汇合类线程平安
线程安全类有两种计划,一种是应用Collections.synchronizedxxx()
办法,一种是应用比方CopyOnWriteList,这两种适宜不同的场景,具体能够参考这两个
1.List汇合
CopyOnWriteArrayList 实现原理
2.set汇合
阻塞队列
形式 | 抛出异样 | 有返回值,不抛出异样 | 阻塞期待 | 超时期待 |
---|---|---|---|---|
增加 | add | offer() | put() | offer(,,) |
移除 | remove | poll() | tack() | poll(,,) |
查看队首元素 | element | peak() | - | - |
四组api中,其中第三组中,阻塞的时候 task,poll,remove是都能够取出数据而后再put的。
SynchronousQueue (狂的演示代码不能阐明问题,因为每次都是线程期待)如果始终put的话,的确队列中只能存在一个值,只有被取出才能够再放。参考
线程池
- 1、2示意外围线程数
- 当候客区满了之后就是启动3、4、5的最大线程数
- 此时如果还是满的就是触发回绝策略
- 当线程完结,3、4、5闲暇工夫达到设置的值后就会主动回收
JMM
小狂笔记中的store 和 write写反了。
单例模式
懒汉式中的dubble check 还要volitaile,避免在两次检测后进行new 的时候呈现指令重排,导致对象还没有实例化实现。一般的单例模式能够通过反射被破解。
原子援用
应用包装类可能会呈现问题,失常的业务逻辑应该是不同的java类。因为在进行compare的时候应用的是==
来判断的。