synchronized是利用锁的机制来实现同步的。
锁机制有如下两种特性:
互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。
可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。
用法:
- 同步方法
- 同步非静态方法
Public synchronized void methodName(){
……
}
-
- 同步静态方法
Public synchronized static void methodName(){
……
}
- 同步代码块
synchronized(this|object) {}
synchronized(类.class) {}
Private final Object MUTEX =new Object();
Public void methodName(){
Synchronized(MUTEX ){
……
}
}
在 Java 中,每个对象都会有一个 monitor 对象,监视器。
- 某一线程占有这个对象的时候,先monitor 的计数器是不是0,如果是0还没有线程占有,这个时候线程占有这个对象,并且对这个对象的monitor+1;如果不为0,表示这个线程已经被其他线程占有,这个线程等待。当线程释放占有权的时候,monitor-1;
- 同一线程可以对同一对象进行多次加锁,+1,+1,重入性
synchronized原理
1代码块加锁
Monitorenter
Monitorexit
2.对方法的加锁
ACC_SYNCHRONIZED
1.6JDK以前重量锁,1.6之后
偏向锁
轻量级锁
重量级锁(等待时间长)
锁之间只会升级,不会重量级往轻量级转换
轻量级向重量级转换会通过自旋锁和锁销处来转换。