# synchronized关键字

Java中的 synchronized关键字是内置的同步机制,用于控制多个线程对共享资源的并发访问。它可以确保同一时间只有一个线程能够访问同步代码块或同步方法,以避免线程安全问题。

# synchronized 的两种使用方式:

  1. 同步方法(Synchronized Method)
  2. 同步代码块(Synchronized Block)

# 1. 同步方法

将整个方法声明为 synchronized,当一个线程访问该方法时,其他线程必须等待该线程执行完毕。

# 示例:

public class Counter {
    private int count = 0;

    // 同步方法,锁住整个方法
    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# 2. 同步代码块

相比同步整个方法,可以选择只同步某个代码块,粒度更小,效率更高。同步代码块通过指定一个锁对象,使得代码块中的部分执行具有互斥性。

# 示例:

public class Counter {
    private int count = 0;
    private final Object lock = new Object();

    // 同步代码块,锁住特定的代码块
    public void increment() {
        synchronized (lock) {
            count++;
        }
    }

    public int getCount() {
        synchronized (lock) {
            return count;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# synchronized 的作用机制

  1. 锁定对象

    • 实例方法:锁定当前对象实例 (this)。
    • 静态方法:锁定类的 Class 对象。
    • 代码块:锁定指定的对象(如 lock 对象)。
  2. 可重入锁 synchronized 是可重入的,意味着如果一个线程已经持有该锁,则可以再次获得同一把锁而不会引发死锁。

# 示例:

public class ReentrantExample {
    public synchronized void methodA() {
        methodB(); // 线程可以再次获取同一把锁
    }

    public synchronized void methodB() {
        // 执行代码
    }
}
1
2
3
4
5
6
7
8
9

# synchronized 的优缺点

# 优点:

  • 简单易用,内置语言级别的支持。
  • 自动释放锁,无需手动解锁,减少死锁的风险。

# 缺点:

  • 粒度较大时性能较低,整个方法被锁定可能导致性能瓶颈。
  • 只能是阻塞式的锁,没有提供超时或中断机制。

# synchronized vs ReentrantLock

  • synchronized 自动管理锁的获取和释放,而 ReentrantLock 需要手动加锁和释放。
  • synchronized 只能用于块或方法,而 ReentrantLock 提供更多的功能(如公平锁、可中断锁等)。
  • ReentrantLock 的粒度和灵活性比 synchronized 更高,但代码复杂性也随之增加。

# 总结

synchronized 是控制线程访问共享资源的基础机制,适用于简单的并发控制场景。在对性能要求较高或者需要更复杂锁机制时,可以考虑使用 java.util.concurrent.locks 包下的高级锁机制如 ReentrantLock

最近更新: 9/24/2024, 10:36:04 PM
备案号:粤ICP备2023124211号-1
Copyright © 2023-2024 StarChenTech All Rights Reserved.