synchronized是Java中的一种同步机制,主要用于控制多线程对共享资源的访问。它有以下三种形式:
1. 锁Java对象:通过在方法前加上synchronized关键字,可以锁定一个Java对象。当一个线程获取了该对象的锁后,其他线程需要等待该线程释放锁后才能访问该对象。这样可以确保同一时刻只有一个线程能够访问共享资源。示例代码如下:
```java
public class SynchronizedDemo {
private Object lock = new Object();
public void synchronizedMethod() {
synchronized (lock) {
// 需要同步的代码块
}
}
}
```
2. 锁Class对象:通过在static方法前加上synchronized关键字,可以锁定一个Class对象。这样可以确保同一时刻只有一个类的所有实例都能够访问这个静态方法。示例代码如下:
```java
public class SynchronizedDemo {
public static void synchronizedMethod() {
// 需要同步的代码块
}
}
```
3. 锁代码块:通过使用{}包围的代码块,可以实现同步。当一个线程进入这个被{}包围的代码块时,其他线程需要等待这个线程执行完毕或者抛出异常后才能进入这个代码块。示例代码如下:
```java
public class SynchronizedDemo {
public void synchronizedMethod() {
String name = Thread.currentThread().getName();
System.out.println("线程:" + name + "准备好了...");
synchronized (this) {
// 需要同步的代码块
}
}
}
```
synchronized的优势主要有以下几点:
- 即使在同步方法中出现异常,JVM也能自动释放锁,避免死锁的发生,无需开发者手动释放锁。
- 当一个线程获取了锁对象后,其他线程需要等待该线程执行完成或者抛出异常后才能继续执行。这有助于确保同一时刻只有一个线程能够访问共享资源。
然而,synchronized也存在一些劣势:
- 必须等到获取锁对象的线程执行完成或者抛出异常后,才能释放锁。无法在中途释放锁或中断正在尝试获得锁的线程。
- 由于不知道多线程竞争锁的结果,因此不够灵活。每个锁仅具有单一的条件(某个对象),不能设置超时时间。