synchronized。当任务要执行被synchronized关键字保护的代码段时,它将检查锁是否可用,然后获取锁,执行代码,释放锁。所有的对象jvm都自动为其添加一个单一的锁,用以监视对该对象的访问,这个锁也称为对象锁。<引自Thinking in Java>
synchronized关键字有几种使用方式,主要如下:
(1) 实例方法上的synchronized关键字
public synchronized void aMethod() { ... }
(2) 类方法上的synchronized关键字
public synchronized static void bMethod() { ... }
(3) synchronized代码块
synchronized (this) { ... } // 第一种形式
Object syncObject = new Object();
synchronized(syncObject) { ... } // 第二种形式
无论是实例方法上、类方法上或是代码块,synchronized关键字都是利用对象锁来实现多个线程对synchronized所指定或包含的代码的访问控制。
对于实例方法,其每个方法都隐含包括一个指向实例自身的this参数。实例方法上的synchronized关键字就是利用该this参数指向的实例的对象锁来控制多线程访问。一旦某个线程获取到该对象锁,在其未释放之前,其他所有线程都无法访问同样以该实例的对象锁作为同步访问控制条件的synchronized实例方法和synchronized(this)代码块。
synchronized关键字利用该类唯一的class类实例的对象所来控制多线程方法。一旦某个线程获取到该类的class实例的对象锁,在其未释放之前,其他所有线程都无法访问同样以该类的class实例的对象锁作为同步访问控制条件的synchronized类方法或显示指定的synchronized(this.class)代码块。
synchronized代码块,synchronized后面紧跟的括号内容是用于指定该synchronized代码块同步访问控制条件(某个对象锁)的对象。需要指出的是,相比实例方法和类方法,synchronized代码块的灵活性更好,它可以任意指定某个实例,并将该实例的对象锁作为该synchronized代码块的同步访问控制条件。
synchronized实例方法还是类方法,都是不可继承的,即在父类中声明的某个synchronized实例方法或类方法,在子类中并不默认保证synchronized同步,必须重新显示添加或synchronized关键字用以保证同步。
总结:任何synchronized关键字标注的方法或是代码块都是通过对象锁来保证同步控制。只要该对象锁被某个线程获取,在其未释放之前,其他任意线程均无法访问同样以此对象锁作为同步控制条件的所有synchronized方法和代码块。