`synchronized` 是 Java 中的一个关键字,用于确保多个线程在访问共享资源时的同步,防止出现数据不一致的问题。它可以确保同一时刻只有一个线程能够执行被 `synchronized` 修饰的代码块或方法。`synchronized` 可以修饰方法或者特定的代码块。
### 修饰方法
当 `synchronized` 修饰一个实例方法时,它锁定的是当前对象的实例(`this`)。如果是静态方法,则锁定的是当前对象的类(Class)对象。
#### 实例方法示例:
```java
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
```
在这个例子中,`increment` 方法和 `getCount` 方法都是同步的。这意味着在任何时刻,只有一个线程可以执行 `increment` 方法来增加计数器的值,或者调用 `getCount` 方法来获取计数器的值。
### 修饰代码块
`synchronized` 也可以用于修饰一个代码块,这样可以更精确地控制需要同步的代码部分。在代码块中,你可以指定一个锁对象(lock object),线程在执行该代码块时会尝试获取该对象的锁。
#### 代码块示例:
```java
public class SharedResource {
private Object lock = new Object();
private int value = 0;
public void increment() {
synchronized(lock) {
value++;
}
}
public int getValue() {
synchronized(lock) {
return value;
}
}
}
```
在这个例子中,我们创建了一个名为 `lock` 的 `Object` 实例作为锁对象。`increment` 方法和 `getValue` 方法中的代码块都是同步的,它们在执行时都会尝试获取 `lock` 对象的锁。
### 注意事项
- `synchronized` 关键字在方法或代码块上的作用范围是不同的。在方法上,它锁定的是当前对象的实例;在代码块中,它锁定的是指定的锁对象。
- 使用 `synchronized` 时,需要考虑锁的粒度。过粗的锁粒度可能会导致性能问题,因为过多的线程竞争同一个锁;过细的锁粒度可能会导致死锁。
- 在使用 `synchronized` 时,还需要注意避免死锁,即两个或多个线程相互等待对方持有的锁。
`synchronized` 是 Java 中最基本的同步机制之一,但它并不是唯一的。随着 Java 并发包的引入,开发者有了更多的选择,如 `ReentrantLock`、`ReadWriteLock` 等,它们提供了更灵活的锁机制。
本文详细解释了Java中的`synchronized`关键字如何实现线程同步,包括修饰方法和代码块的区别,以及如何处理锁的粒度和避免死锁。同时提到了Java并发包提供的更多同步选项。
7477

被折叠的 条评论
为什么被折叠?



