【多线程】Synchronized 关键字

305 阅读1分钟

Synchronized 关键字,用于锁定一个共享可变的资源。当一个线程需要使用该类资源时,需要检查其是否被其它线程占用,如果有其它线程正在使用该资源,则需要等其它线程释放后,当前线程才能调用。

简而言之,被 synchronized 修饰的一段逻辑将会成为一个同步块,在任何时间内都只允许一个线程访问。

加锁的层次

1. 对象锁

每个对象都有各自的锁,互不影响

平常所说的类锁,是一种特殊的对象锁。

2. 方法锁

1)修饰普通方法,锁对象默认为当前实例

public synchronized void method() {
    ……
}

2) 修饰 static 方法,锁对象为当前类

public static synchronized void classLock() {
    ……
}

无论方法正常执行完还是抛出异常,都会释放锁

3. 代码块锁

示例代码如下:

public void method() {
    Object o = new Object();
    synchronized (o) {
        ……
    }
}

当一个线程访问对象的一个被 synchronized(this) 修饰的代码块时,其它线程对该对象中其它 synchronized(this) 修饰的代码块的访问将被阻塞。

当一个线程访问一个对象中的一个加锁代码块时,其它线程可以访问非加锁的代码部分。

Synchronized 原理

Java 内部使用监视器锁(或称内部锁)来提供同步,这些监视器绑定到一个对象,以此保证所有对象的所有同步块只能有一个线程访问它们。

注意事项

  • 锁对象不能为空,因为锁信息都保存在对象头里;
  • 作用域不宜过大,会影响程序执行速度;
  • Synchronized 时非公平的,可能会导致饥饿现象;

参考:

www.baeldung.com/java-synchr…

pdai.tech/md/java/thr…

redspider.gitbook.io/concurrent/…