Synchronized

1. Synchronized 关键字的作用

synchronized 是 Java 中的关键字,用于实现线程的同步,确保多个线程之间对共享资源的安全访问。它可以被用于方法、代码块以及静态方法上。

  • 在方法上使用: 锁定整个方法,确保同一时间只有一个线程可以执行该方法。

    public synchronized void synchronizedMethod() {
        // 同步的方法体
    }
    

  • 在代码块上使用: 锁定指定的对象,只有获得该对象的锁的线程才能执行该代码块。

    public void someMethod() {
        // 非同步代码
    
        synchronized (lockObject) {
            // 同步代码块
        }
    
        // 非同步代码
    }
    

2. Synchronized 原理

synchronized 关键字的原理涉及到对象头中的锁标志位(Lock Flag)和互斥量(Mutex)。

  • 获取锁: 当线程尝试进入一个使用 synchronized 修饰的方法或代码块时,它会尝试获取对象的锁。

  • 锁标志位: 对象头中有一个锁标志位,初始值为无锁状态。当线程成功获取锁时,锁标志位变为锁定状态。

  • 互斥量: 如果锁已经被其他线程持有,当前线程会进入阻塞状态。此时,JVM 会使用互斥量来协调线程的访问。

3. 锁优化

a. 轻量级锁

JDK 1.6引入了轻量级锁,旨在减少传统的重量级锁的性能开销。在没有竞争的情况下,JVM 会尝试使用轻量级锁来提高性能。轻量级锁采用CAS(Compare and Swap)操作来尝试获取锁,避免了传统锁的互斥操作。

public class LightweightLockExample {
    private int sharedResource = 0;

    public void synchronizedMethod() {
        synchronized (this) {
            // 同步代码块
            sharedResource++;
        }
    }
}

b. 偏向锁

JDK 1.6还引入了偏向锁,该锁假设在大多数情况下,锁总是由同一线程多次获得。因此,当一个线程获得锁时,会标记对象头,并在以后尝试获取锁时,不再使用互斥,直接进入临界区。,避免了对锁的互斥操作,提高了单线程访问的性能。

public class BiasedLockExample {
    private int sharedResource = 0;

    public synchronized void synchronizedMethod() {
        // 同步代码块
        sharedResource++;
    }
}
c. 无锁优化

针对一些高度竞争的情况,JDK 1.8 引入了无锁优化。通过一些乐观锁的机制,避免了对锁的争用。

import java.util.concurrent.atomic.AtomicInteger;

public class NoLockOptimizationExample {
    private AtomicInteger sharedResource = new AtomicInteger(0);

    public void nonBlockingMethod() {
        // 非阻塞代码
        sharedResource.incrementAndGet();
    }
}

总结

synchronized 关键字在Java中起到了关键的同步作用,确保多线程访问共享资源的安全性。

你可能感兴趣的:(java)