锁之synchronized
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了锁之synchronized相关的知识,希望对你有一定的参考价值。
synchronized与Lock的区别
synchronized
synchronized是JVM中的关键字,加锁和释放锁都是通过JVM自动完成。说到这个点,就需要说明一下class和其instance在JVM的存储情况。class存储在持久层,并且会存储锁的信息。object实例存储在新生代或者老年代,同样其也存储了该实例对象的锁信息。
class类锁
public class User{
public static synchronized void doOne(){}
public static synchronized void doTwo(){}
}
等同于下面的代码:
public class Test{
public void test(){
synchronized(User.class){
// do something
}
}
}
上面的例子是一个class类锁,即一旦调用User.doOne()方法,那么整个User.class都会被锁定;如果其他线程再调用User.doTwo()方法,会被阻塞;当然同一个线程的话,是不会阻塞的,因为synchronized锁是可重入锁。
Object实例锁
public class User{
public synchronized void doOne(){}
public synchronized void doTwo(){}
}
等同于下面的代码:
public class Test{
private User user = new User();
public void test(){
synchronized(user){
// do something
}
}
}
上面的例子就是一个实例的对象锁,每个user实例的锁是独立的。如果同一个user实例被多个线程调用doOne()那么会出现锁阻塞;如果每个线程都有自己的user实例,则doOne()、doTwo()调用相互不影响。
statement代码片段锁
public class User{
private static Object lockObj = new Object();
public void doOne(){
synchronized(lockObj){
// do something
}
}
public void doTwo(){
synchronized(lockObj){
// do something
}
}
}
上面的例子是通过方法中的代码片段来实现锁机制的。它的锁粒度是lockObj这个数据。在多线程下,doOne()和doTwo()不会阻塞,只有在synchronized(lockObj)才会阻塞。
以上是关于锁之synchronized的主要内容,如果未能解决你的问题,请参考以下文章