|
|
51CTO旗下网站
|
|
移动端

1.7.2 synchronized关键字

《Java多线程与Socket:实战微服务框架》第1章多线程基础,本书尽量采用简要和通俗易懂的方式来介绍多线程知识。本节为大家介绍synchronized关键字。

作者:庞永华来源:电子工业出版社|2019-03-26 15:55

【大咖·来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》

1.7.2 synchronized关键字

synchronized是Java中的关键字,被用于标记一个方法或代码块。它通过显式或隐式地给对象上“锁”的方式,将自己的作用域变成了一个临界区(参见1.6.2节),从而实现线程之间的同步。

注:理解Java的内置锁(基于对象监视器的锁)对于理解synchronized关键字的作用域和上锁动作非常关键。请先阅读并理解1.6.4节的内容。

当多个线程都执行到被synchronized关键字修饰的方法或代码块,也就是准备进入临界区时,它们将通过竞争指定对象的“锁”来取得进入相应临界区的权限。一旦某个线程获得了对象的“锁”,进入了某个临界区,其他试图进入此临界区的线程将被阻塞,并等待这个线程离开临界区(自动释放相应的“监视器锁”)或主动(暂时性地)释放“锁”(调用“锁”对象的wait()方法)。

synchronized关键字有以下几种用法。

(1)修饰一个代码块,称为同步块,其作用的范围是“{}”括起来的代码段,作用的对象是“()”内的对象,表示要获得该对象的“锁”。

  1. // 此句要求当前线程获得data对象的内置锁  
  2. synchronized (data) {  
  3. data.add(i);  

(2)修饰一个非静态方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是拥有这个方法的对象。也就是说,要执行此方法,需要先获得拥有此方法的对象的“锁”。要注意的是,在定义接口方法时不能使用synchronized关键字;构造函数也不能使用synchronized关键字来修饰,但它的方法体内可以使用synchronized来声明代码块。

  1. // 此句要求当前线程获得add方法所属对象的内置锁  
  2. public synchronized void add(int i) {  
  3. data.add(i);  

(3)修饰一个静态的方法。其作用的范围是整个静态方法,作用的对象是这个类的所有实例对象!原因是静态方法是属于类的,而不属于对象。调用被synchronized修饰的静态方法时,锁定的是这个类对象本身,因此也就会影响对该类所有实例的访问。

  1. // 此句要求当前线程获得add方法所属类的所有对象的内置锁  
  2. public synchronized static void add(int i) {  
  3. data.add(i);  

(4)修饰一个类。其作用的范围是synchronized后面括号括起来的部分。和修饰类的静态方法一样,此时作用的对象是这个类对象本身,并影响对其所有实例的访问。

  1. // 此句要求当前线程获得MyRunnable类的所有对象的内置锁  
  2. synchronized (MyRunnable.class) {  
  3. data.add(i);  

我们将1.6.1节中示例代码的run()方法稍加修改,并做前后对比:

  1. public void run() {  
  2. int v = page * 10000;  
  3. for (int i = 0; i < 10000; i++) {  
  4. // 增加synchronized同步块,基于data对象增加同步锁  
  5. synchronized (data) {  
  6. data.add(v++);  
  7. }  
  8. count++;  
  9. Thread.yield();  
  10. }  

另外,要注意的是,synchronized关键字并不属于方法定义的一部分,不能被继承。如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,则在子类中的这个方法默认情况下并不是同步的,仍然需要在子类的这个方法上也加上synchronized关键字才可以。

synchronized关键字的不同用法,会影响“锁”的范围和粒度。这会给程序执行造成很大的性能差别,甚至会引起死锁。具体示例可参见9.4.5节。


喜欢的朋友可以加入官方的读书群

51CTO读书频道二维码


51CTO读书会第9群:808517103

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

Jenkins Pipeline可持续化集成

Jenkins Pipeline可持续化集成

优化运维流水线
共3章 | youerning

198人订阅学习

笑熬浆糊之职场那些事

笑熬浆糊之职场那些事

IT人的职场心法
共22章 | Bear_Boss

79人订阅学习

Redis运维秘籍

Redis运维秘籍

运维标配技术
共15章 | one叶孤舟

199人订阅学习

读 书 +更多

PHP程序开发范例宝典

本书全面介绍了应用PHP进行网站开发的各种技术和技巧。全书分为20章,内容包括PHP的运行环境配置、表单及表单元素的应用、CSS与JavaScript...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客