Java Synchronized 全局锁:理解与实践
在 Java 编程中,多线程编程是一个经常遇到的主题,而 synchronized
关键字是用于处理线程安全问题的一个重要工具。本文将详细探讨“全局锁”概念,并通过代码示例来加深理解。
什么是全局锁?
全局锁是指在整个应用程序范围内只有一个线程能够访问某一资源。这通常是通过 synchronized
关键字实现的。全局锁确保在同一时刻,只有一个线程可以执行特定的方法或代码块,从而避免数据不一致或竞争条件的发生。
Synchronized 的使用
synchronized
可以用于方法和代码块。其基本语法如下:
public synchronized void synchronizedMethod() {
// 需要线程安全的代码逻辑
}
或者使用代码块:
public void methodWithBlock() {
synchronized (this) {
// 需要线程安全的代码逻辑
}
}
其中,this
表示当前对象的监视器锁。
全局锁与局部锁的对比
使用全局锁的方式会限制其他线程的并行执行,可能导致性能下降。以下是全局锁和局部锁的对比:
特性 | 全局锁 | 局部锁 |
---|---|---|
锁范围 | 整个类/对象 | 代码块 |
性能影响 | 性能下降,线程饥饿 | 影响较小,改善并行执行 |
锁控制 | 简单,但不灵活 | 更灵活,锁和队列可控 |
示例代码
以下代码展示了全局锁的使用。我们将定义一个简单的银行账户类,处理存款和取款操作:
public class BankAccount {
private int balance = 0;
// 全局锁:synchronized 方法
public synchronized void deposit(int amount) {
balance += amount;
}
public synchronized void withdraw(int amount) {
if (balance >= amount) {
balance -= amount;
}
}
public int getBalance() {
return balance;
}
}
在上述代码中,deposit
和 withdraw
方法使用了全局锁,以确保在任何给定时刻只允许一个线程修改账户余额。
线程操作示例
以下是一个线程操作的示例,展示了如何调用这些方法:
public class Main {
public static void main(String[] args) {
BankAccount account = new BankAccount();
// 创建存款线程
Thread depositThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
account.deposit(100);
System.out.println("Deposited: 100, Current Balance: " + account.getBalance());
}
});
// 创建取款线程
Thread withdrawThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
account.withdraw(50);
System.out.println("Withdrew: 50, Current Balance: " + account.getBalance());
}
});
depositThread.start();
withdrawThread.start();
}
}
类图
下面是 BankAccount
类的类图:
classDiagram
class BankAccount {
-int balance
+void deposit(int amount)
+void withdraw(int amount)
+int getBalance()
}
结尾
全局锁在 Java 中是一种有效的同步机制,能够解决线程安全问题。然而,它也会导致线程的阻塞,从而影响程序的性能。在设计时,需要权衡全局锁的使用与局部锁的效率。理解这一点对于开发高效且线程安全的 Java 应用程序至关重要。希望通过本篇文章与代码示例,能使你更好地理解 Java 中的全局锁。