NO.25 synchronized关键字画像:开胃菜

synchronized关键字

synchronized关键字可用于函数修饰符,也可用作函数内的语句块修饰符。对于该关键字,很多程序员老铁有一个错误的认知:由于代码被关键字synchronized保护着,因此同一时刻只能有一个线程才能执行它。

但是,这绝不是synchronized的全部,synchronized也不是从表面看起来那样的简单,今天我们一起来看看。

synchronized修饰非静态函数

对于成员函数,关键字synchronized其实并不是锁定函数或代码,它锁定的是对象。每个对象有且只有一个lock与之相关联,当代码进入关键字synchronizede修饰的函数或代码时,就会试着去获取与该对象相关联的lock,如果该lock已被占用则会被阻塞;如果该lock未被占用则会进入并执行修饰的代码。

代码1:

public class NoStaticSyncTest {
    //情况1:synchronized修饰了该成员函数
    //该函数能被执行,则意味则持有了调用
    //该函数的对象引用所持有的lock
    public synchronized void subroutine1(){

    }

    //情况2:synchronized修饰了this
    //进入该代码块,获得的锁与情况1相同
    public void subroutine2(){
        synchronized(this){
        //TODO
        }
    }

    //情况3:synchronized修饰了pt对象
    //进入该代码块,则获得了pt对象所持有的lock
    public void draw(java.awt.Point pt){
        synchronized(pt){
            //TODO
        }
    }
}

synchronized修饰静态函数

对于静态(static修饰)成员函数,关键字synchronized获取的lock,与上述非静态成员函数获取的lock不一致;当我们调用一个synchronized static函数时,获得的lock将与定义该函数的类的class对象相关联(而不是与调用函数的那个对象相关联)。当我们对一个用synchronized去修饰【类名.class】时,获得的也是同样的那个lock,也就是获得的lock将与定义该函数的类的class对象相关联。

代码2:

public class StaticSyncTest {
    //情况4:synchronized修饰了该成员函数
    //该函数能被执行,则意味则持有StaticSyncTest.class
    //这样class对象所持有的锁
    public synchronized static void subroutine1(){

    }

    //情况5:synchronized修饰了this
    //进入该代码块,获得的锁与情况4相同
    public void subroutine2(){
        synchronized(StaticSyncTest.class){
            //TODO
        }
    }
}
  1. 关键字synchronized可用作函数修饰符;也可用于函数内的语句。
  2. 关键字synchronized并不是锁定函数或代码,它锁定的是该函数或代码所属的对象;并且,每个对象只有一个lock与之相关联。
  3. 当synchronized被当做函数修饰符时,它所取得的lock将被交给函数调用者所属的某对象。
  4. 当synchronized用于修饰对象引用时,则取得的lock将被交给该引用所指向的对象。
  5. 同步控制:调用该函数之线程将会取得对象的lock。持有对象A之lock,意味另一个通过synchronized函数或synchronized语句来申请对象A之lock的线程,在该lock被释放之前将无法获得满足;然而如果另外一个线程对对象A所属类之另一对象B调用相同的synchronized函数或synchronized区块,可以获得对象B之lock。
  6. synchronized函数或synchronized区段内的代码在同一时刻下可由多个线程执行,前提是只要是对不同的对象调用该函数。
  7. 当调用一个synchronized static 函数时,获得的lock将与定义该函数的class相关联,而不是与调用函数的那个对象相关联。当synchronized修饰的是A.class时,获得的lock也是与上述相同,即与class相关联。

转载自公众号:代码荣耀
图1

猜你喜欢

转载自blog.csdn.net/maijia0754/article/details/80796925