隐式锁,又称线程同步synchronized
synchronized 是Java语言的关键字,修饰一个方法或者一个代码块。
保证在同一时刻最多只有一个线程执行该段代码。
Synchronized是在JVM层面上实现的,可以通过一些监控工具监控synchronized的锁定,当代码执行时出现异常,JVM会自动释放锁定。当只有少量竞争者的时候,Synchronized是一个很好的通用的锁实现,synchronized的锁是准对一个对象的。
修饰的地方:
声明方法:
1 public synchronized void add() { 2 // 方法体 3 }
某一代码块使用synchronized(Object) ,指定锁对象:
1 public int add(int number) { 2 3 synchronized (this) { 4 5 // 一次只有一个线程进入 6 } 7 }
其中synchronized(Object) 中的Object 可以是任意对象。(建议另外指定一个小的对象值,不建议使用方法参数和this对象)
修饰在方法体上的synchronized默认的锁的对象就是当前对象本身。等同于synchronized(this){} 修饰代码块的用法。
隐式规则:
(1)当两个线程访问同一个对象object中的这个synchronized(this)同步代码块时,同一个时间内,只能有一个线程得到执行,另一个线程等待执行。
(2)当一个线程访问object中的这个synchronized(this)同步代码块时,另一个线程仍然可以访问object中的非synchronized(this)同步代码块。
(3)当一个线程访问object中的这个synchronized(this)同步代码块时,其它线程对object中所有其它synchronized(this)同步代码块的访问将阻塞。
同步方法体:
1 public synchronized void add() { 2 // 方法体 3 }
注:排队在方法体外,获得锁后,进入方法体还得分配资源,需要一定的时间。
同步代码块:
1 public int add(int number) { 2 3 synchronized (this) { 4 5 // 一次只有一个线程进入 6 } 7 }
注:方法体内加锁。进入了方法,排队在方法体内。
最优写法:
1 // 锁是对象, 加锁和释放锁都需要此对象的资源, 所以对象越小越好。 2 private byte[] lock = new byte[1]; 3 public void add(int number) { 4 5 synchronized (lock) { 6 // TODO 7 } 8 }
更多线程安全链接:

浙公网安备 33010602011771号