我们在日常编程中,经常遇到并发问题,如果不控制,会带来意想不到的的后果,其结果往往和我们的预期不符。
synchronized关键字可以控制并发 ,下面我们将讲一下这个关键字的两种用法。
两种用法:
一,对象锁,一般有两种形式。
(1)synchronized加在代码块中。
(2)synchronized加在方法上。
二,类锁,一般也有两种形式。
(1)synchronized加在static方法上
(2)代码块中synchronized(*.class){}
synchronized有两个性质:
一,可重入性,一句话,当一个线程获得了锁开始执行synchronized方法,但是此方法中又调用了另一个synchronized方法,此时直接调用,不用在等待获取锁,这就是锁的可重入性。可以避免死锁,提高封装性。粒度是线程,不是调度。
二,不可中断。
synchronized原理
加锁和解锁原理,首先要了解Monditorenter和Monditorexit指令。
可重入性原理,加锁计数器。
缺陷
效率低,不能中断一个正在试图获取锁的线程,而且试图获取锁是不能设置超时,而且无法感知是否成功获取到锁。
面试常见问题
使用注意点:锁对象不能为空,作用域不宜过大,避免死锁
如何选择Lock和synchronized?
优先级,首先选择java.util.current包中类的及线程安全成熟的工具类,然后选择synchronized,其次是Lock。
思考题
1,多线程等待同一个synchronized锁的时候,JVM如何选择下一个获取锁的线程?
这就牵扯到JVM的调度算法。
2,synchronized使得同时只有一个线程可以执行,性能较差,有什么办法可以提升性能?
3,我想更灵活地控制锁的获取和释放,怎么办?
4,什么是锁的升级、降级?什么是JVM里的偏斜锁、轻量级锁、重量级锁?
欢迎大家补充,对思考题可以在评论区答复。