持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
背景
大部分同学学习Java的时候接触的第一个关于锁的知识肯定就是synchronized,但是你真的了解它吗?今天我们就来简单梳理下关于synchronized的简单知识。
用法
synchronized修饰普通方法
被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象,即锁的是调用这个方法的对象。
public synchronized void method()
{
}
public void method()
{
synchronized(this) {
}
}
上面2种方式都相当于是修复普通方法,都是都是锁定了整个方法的内容,当线程进入此方法或者此代码块后,其他线程不可进入。
synchronized修饰同步语句块
被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,锁住的是调用这个代码块的对象。同步语句块和同步方法类似,都是锁的对象。只不过同步方法块更灵活,锁的粒度可以更好的得到控制。 需要注意的是,当一个线程在访问某对象的同步方法或者同步语句块的时候,其他线程不能访问其他同步方法或者同步语句块,但是可以访问其他非同步方法和非同步语句块。
synchronized修饰静态的方法
其作用的范围是整个静态方法,即锁住的是整个类,和这个类对应的所有对象。 我们知道静态方法我关联类的,而不是关联对象的,所以当在静态方法上加锁那就是相当于给整个类加了锁。所以当在调用一个类的加锁静态方法时,该类的对象也是被加了锁的。即通过对象调用非静态同步方法也是无法进入的。 如图所示:
synchronized修饰类
其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象和这个类。
class TTT {
public void test() {
synchronized(TTT.class) {
}
}
}
同样修饰类的时候也是给整个类及其对象都加了锁
总结
根据以上的结论,可以得出如果synchronized作用的对象(方法或者方法块)是非静态的,那么它锁住的就是对象;但是如果synchronized作用的对象是一个静态方法或一个类,那么它锁住的就是类,同样就锁住了该类的所有对象。