CPU在多个线程之间切换,有可能会导致某些重要的指令不能完整的执行,会出现数据的问题,请问出现线程安全问题的三个条件?
1.多个线程
2.同一时间
3.执行同一段指令或者修改同一个变量
线程安全问题的解决方案
给程序上锁,让当前线程完整执行一段指令,执行完再释放锁,让其他的线程再继续执行
同步代码块、同步锁、同步方法 三种锁的对比:
粒度:同步方法的粒度高于 同步代码块与同步锁,而粒度来讲同步代码块与同步锁是相同的
编程简便:同步方法简便高于同步代码块,同步代码块高于同步锁
性能:同步锁性能为最优,其次是同步代码块,最后是同步方法
功能性与灵活性:同步锁高于同步代码块,最后是同步方法
上锁的方式
1.同步方法
a.给方法添加上synchronized关键字(给整个方法上锁)
同步方法运行的过程:当前线程调用方法后,方法上锁,其他线程无法执行,调用结束以后再释放锁
2.同步代码块
a.粒度比同步方法小,粒度越小越灵活,性能越高
同步代码块上锁方式:锁住对象,对当前的线程进行控制(任何对象都可以作为锁,但是对象不能是局部变量)
3.同步锁
在java.concurrent并发包中的Lock接口
基本方法:1.lock()上锁
2. unlock()释放锁
常见实现类:1.ReentrantLock 重入锁
2. WriteLock 写锁
3.ReadLock 读锁
4.ReadWriteLock 读写锁
使用方法:先定义同步锁对象,上锁,再释放锁
synchronized的基本的原理(解析):
代码一旦被synchronized包含了,JVM会启动自动监视器 对这段指令进行监控,线程执行这一段代码的时候,监视器会判断锁对象是否有其他的线程持有,如果其它线程持有,当前线程就无法执行,等待锁释放
如果没有锁其他线程持有,当前线程就持有锁,进行执行代码
悲观锁和乐观锁的区别:
悲观锁:悲观锁是重量级的 它觉得代码全部都不安全 所以占用资源更多,降低程序的性能。悲观锁应用在线程竞争比较频繁的情况,多写少读的场景。
乐观锁:相对于悲观锁,乐观锁更加轻量级,所以性能更高。应用于线程竞争比较少的情况,多读少写的场景。
总结:主要讲的是线程安全问题,我们可以把线程安全看做生活中的例子,每种锁都有自己的优势与劣势,主要了解到三种锁的每个要点和执行过程。