1. 同步方法
当 `synchronized` 用于修饰方法时,表明同一时刻只有一个线程可以执行该方法。以下是示例代码:
java
class Counter {
private int count = 0;
// 同步方法
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class SynchronizedMethodExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
// 创建两个线程
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// 启动线程
thread1.start();
thread2.start();
// 等待线程执行完毕
thread1.join();
thread2.join();
// 输出结果
System.out.println("Count: " + counter.getCount());
}
}
在这个示例中,`increment` 方法被 `synchronized` 修饰,这意味着同一时刻只有一个线程能够执行该方法,进而保证了 `count` 变量的线程安全。
2. 同步代码块
`Synchronized` 也能够用于修饰代码块,这样可以更细粒度地控制同步范围。示例如下:
java
class Counter {
private int count = 0;
private final Object lock = new Object();
public void increment() {
// 同步代码块
synchronized (lock) {
count++;
}
}
public int getCount() {
return count;
}
}
public class SynchronizedBlockExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
// 创建两个线程
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// 启动线程
thread1.start();
thread2.start();
// 等待线程执行完毕
thread1.join();
thread2.join();
// 输出结果
System.out.println("Count: " + counter.getCount());
}
}
在这个示例中,`increment` 方法里的 `synchronized (lock)` 代码块保证了同一时刻只有一个线程能够执行 `count++` 操作,从而保证了线程安全。
3. 静态同步方法
当 `synchronized` 用于修饰静态方法时,表明同一时刻只有一个线程可以执行该静态方法,并且所有该类的实例共享同一把锁。示例如下:
java
class StaticCounter {
private static int count = 0;
// 静态同步方法
public static synchronized void increment() {
count++;
}
public static int getCount() {
return count;
}
}
public class StaticSynchronizedMethodExample {
public static void main(String[] args) throws InterruptedException {
// 创建两个线程
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
StaticCounter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
StaticCounter.increment();
}
});
// 启动线程
thread1.start();
thread2.start();
// 等待线程执行完毕
thread1.join();
thread2.join();
// 输出结果
System.out.println("Count: " + StaticCounter.getCount());
}
}
在这个示例中,`increment` 是静态同步方法,所有 `StaticCounter` 类的实例共享同一把锁,保证了 `count` 变量的线程安全。
总结
- **同步方法**:对整个方法进行同步,锁的是当前对象实例(对于非静态方法)或者类对象(对于静态方法)。
- **同步代码块**:能够更细粒度地控制同步范围,锁的是指定的对象。
- **静态同步方法**:对静态方法进行同步,锁的是类对象。
使用 `synchronized` 关键字能够有效解决多线程环境下的线程安全问题,但同时也会带来一定的性能开销,所以要谨慎使用。