synchronized 详解

Synchronized 简述

  • 编写一个类时或者方法、码块时,如果其中的代码可能运行于多线程环境下,那么就要考虑同步的问题
  • Java中内置了语言级的同步关键字-synchronized,这大大简化了Java中多线程同步的使用
  • synchronized 是Java中的关键字,是一种同步锁,注意用于修饰方法、代码块
  • 例如用Account类表示一个银行账户信息,主程序中生成100个线程,再启动它们,每一个线程都对此账户存100元,然后又取出100元。最终账户的余额应该还是1000元。如果线程不同步,则运行的结果极可能超出我们的想像

注意事项

  • synchronized关键字不能继承
  1. synchronized 可以定义方法,但synchronized并不属于方法定义的一部分,因此synchronized关键字不能被继承。
  2. 如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,而必须显式地在子类的这个方法中加上synchronized关键字才可以。
  3. 当然可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,但子类调用了父类的同步方法,因此,子类的方法也就相当于同步了。
  • 定义接口方法时不能使用synchronized关键字
  • 构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步

修饰代码块

  • 被修饰的代码块称为同步代码块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象,对不同线程中的同一对象有效——对象锁; 

synchronized this  对象锁

  • synchronized(this) 与下面"修饰普通方法"效果完全一致
  • 如下所示:synchronized(this)是对象锁,可以同步不同线程中的同一个对象,下面能达到同步的目的


  • 如下所示:不同线程中对象不同,sysnchronized(this)是无法同步的。
  • 线程thread1执行的是第一个匿名对象中的synchronized代码,而线程thread2执行的是第二个匿名对象中的synchronized代码,而 synchronized锁定的是对象,这时会有两把锁分别锁定第一个匿名对象和第二个匿名对象,而这两把锁是互不干扰的,不形成互斥,所以两个线程可以同时执行。


synchronized  Class  类锁

  • 作用的范围是synchronized(Class) 后面括号括起来的部分,作用的对象是这个类的所有对象——类锁。




修饰普通方法 对象锁

  • 这里所说的"普通方法"是指"非静态方法"
  • 被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象,对不同线程中的同一对象有效————对象锁; 
  • 一个线程访问一个对象的synchronized(this){}代码块、或synchronized方法时,别的线程可以访问该对象的非synchronized代码块和方法而不受阻塞。

  • 一个线程访问一个对象的synchronized(this){}代码块、或synchronized方法时,别的线程不可以访问该对象的其它synchronized代码块和方法

同一对象


不同对象


修饰静态方法 类锁

  • 作用的是整个静态方法,作用的对象是这个类的所有对象——类锁; 
  • 静态方法是属于类的而不属于对象的,同样synchronized修饰的静态方法锁定的是这个类的所有对象。








猜你喜欢

转载自blog.csdn.net/wangmx1993328/article/details/80880140