隐式锁,又称线程同步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 }

 

更多线程安全链接:

线程安全

posted @ 2017-12-26 17:32  晕菜一员  阅读(466)  评论(0)    收藏  举报