在 Java 中,`synchronized` 关键字用于控制多个线程对共享资源的访问。当一个线程访问一个对象的同步方法时,它会持有与该对象相关的锁,直到同步方法完成为止。其他线程在执行该对象的任何同步方法之前必须等待锁被释放。
### 同步方法
当你在方法声明上使用 `synchronized` 关键字时,该方法被称为同步方法。这意味着同一时间只有一个线程可以执行该对象的所有同步方法。
示例:
```java
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
```
在上面的例子中,任何时刻只有一个线程可以执行 `increment` 或 `getCount` 方法,因为这些方法都是同步的,并且它们在同一把锁上同步——即 `Counter` 对象的 `this` 锁。
### 同步代码块
除了同步方法,`synchronized` 关键字还可以用来同步一个代码块。这时,你指定一个锁对象,线程在进入同步代码块之前必须持有该锁。
示例:
```java
public class Counter {
private int count = 0;
private final Object lock = new Object();
public void increment() {
synchronized(lock) {
count++;
}
}
}
```
在这个例子中,我们创建了一个私有的 `lock` 对象作为锁。任何想要进入 `increment` 方法的线程必须先获得这个 `lock` 对象的锁。
### 注意事项
1. 死锁:当多个线程互相等待对方持有的锁时,可能会发生死锁。
2. 性能影响:虽然同步可以解决并发问题,但它也可能降低程序的性能,因为线程需要花费时间等待锁。
3. 锁的选择:选择合适的锁很重要。通常,使用对象的自然锁(如方法的 `this` 锁)是最简单的方法。
使用 `synchronized` 关键字是解决多线程并发问题的一种基础且有效的方法,但需要谨慎使用,以避免潜在的问题。
网友评论