- 在java虚拟机环境下,需要对以下两种线程共享的区域进行加锁
1.保存在堆里面的对象
2.保存在方法区里的类变量
java的锁机制
实际在jvm中每个对象或者类都会绑定一个监视器相关的锁,为了实现监视器的排他性监视功能,分别绑定对象的实例变量和类的实例变量。一个锁代表每次只能有一个线程进行访问,一个线程可以对对象多次加锁控制,对于每个对象,jvm维护一个加锁计数器,线程每次获得一个对象就加1,释放这个对象时就减1,直到加锁计数器为0时才真正释放这个对象的锁。java编程人员不需要自己动手加锁,对象锁是java虚拟机内部使用的。在java程序中,只需要使用synchronized块或者synchronized方法就可以标志一个监视区域。当每次进入一个监视区域时,java 虚拟机都会自动锁上对象或者类。
保证线程安全方式:synchronized和lock锁
synchronized
注意:
对于同步方法,锁是当前实例对象。
对于同步方法块,锁是Synchonized**括号里配置的对象**。
对于静态同步方法,锁是当前对象的Class对象。
Lock
使用锁来保证线程安全
区别
首先他们肯定具有相同的功能和内存语义。
1、与synchronized相比,ReentrantLock提供了更多,更加全面的功能,具备更强的扩展性。例如:时间锁等候,可中断锁等候,锁投票。
2、ReentrantLock还提供了条件Condition,对线程的等待、唤醒操作更加详细和灵活,所以在多个条件变量和高度竞争锁的地方,ReentrantLock更加适合(以后会阐述Condition)。
3、ReentrantLock提供了可轮询的锁请求。它会尝试着去获取锁,如果成功则继续,否则可以等到下次运行时处理,而synchronized则一旦进入锁请求要么成功要么阻塞,所以相比synchronized而言,ReentrantLock会不容易产生死锁些。
4、ReentrantLock支持更加灵活的同步代码块,但是使用synchronized时,只能在同一个synchronized块结构中获取和释放。注:ReentrantLock的锁释放一定要在finally中处理,否则可能会产生严重的后果。
5、ReentrantLock**支持中断处理**,且性能较synchronized会好些。