线程安全的含义:当多个线程访问一个对象的时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的。
java语言中线程安全的五个维度(安全性从高到低):
1、不可变
2、绝对线程安全
3、相对线程安全
4、线程兼容
5、线程对立
一、线程安全的实现方法
1.互斥同步(悲观锁):
定义:
互斥:实现同步的一种手段,实现方式有:临界区、互斥量、信号量
同步:在多个线程并发访问共享数据时,保证共享数据在同一个时刻只被一个线程使用。
实现方式:
1.synchronized:实现原理:在同步块前后分别形成monitorenter和monitorexit,
当执行monitorenter时,先尝试获取对象锁,如果对象没被锁定,或已经有了这个对象的锁,把锁的计数器加1,
当执行monitorexit时,锁计数器减1,当计数器为0时,锁释放。
2.ReentrantLock(重入锁):
与sychronized类似,但多具有以下几个功能:
1.等待可中断:当持有锁的线程长期不释放锁的时候,正在等待的线程可以放弃等待
2.可实现公平锁:通过带布尔值的构造函数使用公平锁(按申请时间获取的锁)
3.可以绑定多个条件的锁:调用newcondition()绑定多个条件
2.非阻塞同步(乐观锁):
定义:先行进行操作,没有争用共享数据,操作成功;反之,就产生了冲突,采取补偿措施(不断重试)。
3.无同步方案:
1.可重入代码(纯代码):在代码执行的任何时刻中断它,在控制权返回后,源程序不会出现任何错误
2.线程本地存储:所需要的数据必须与其他代码共享,把共享数据的可见范围限制在同一个线程之内。