什么是 synchronized
- synchronized 一个关键字,用于实现线程同步。其主要作用是控制多个线程对共享资源的访问,确保被 synchronized 修饰的代码块或方法同一时间只有一个线程可以执行,从而避免数据不一致的问题
为什么需要 synchronized
- 在多线程编程中,多个线程可能同时访问和修改共享数据。如果不加以控制,可能会导致数据不一致或程序错误。例如:一个线程正在写入一个变量,另一个线程正在读取该变量,在这种情况下,可能会读取到不完整或错误的数据。为了解决这个问题,使用 synchronized 来确保某个代码块或方法在同一时间只被一个线程执行
synchronized 的用法
修饰实例方法
-
当 synchronized 用来修饰一个实例方法时,它会对当前对象实例 (
this
) 加锁。也就是说,同一个对象的所有 synchronized 实例方法在同一时间只能被一个线程访问public class Counter { private int count = 0; // synchronized 修饰符用于同步方法 // increment() 方法被 synchronized 修饰,这意味着如果有多个线程尝试同时调用 increment() 方法,只有一个线程可以进入,其他线程必须等待,直到当前线程执行完毕 public synchronized void increment() { count++; } public int getCount() { return count; } }
修饰静态方法
-
当 synchronized 用来修饰一个静态方法时,它会对当前类的 Class 对象加锁。这意味着同一个类的所有 synchronized 静态方法在同一时间只能被一个线程访问
public class Counter { private static int count = 0; // synchronized 修饰符用于同步静态方法 // increment() 方法是静态方法,被 synchronized 修饰后,所有线程在同一时间只能有一个线程可以执行这个方法 public static synchronized void increment() { count++; } public static int getCount() { return count; } }
修饰代码块
-
synchronized 还可以用来修饰代码块,这样可以锁定一个特定的对象,而不是整个方法。这种用法可以提供更细粒度的控制,可以提高性能
public class Counter { private int count = 0; private final Object lock = new Object(); public void increment() { // increment() 方法中的代码块被 synchronized 锁定,锁定对象是 lock。只有一个线程可以进入 synchronized (lock) 内部的代码块,其他线程需要等待 synchronized (lock) { count++; } } public int getCount() { return count; } }
总结
-
synchronized 是一种同步机制,用于防止多个线程同时访问共享资源
-
可以使用 synchronized 修饰方法或代码块,以确保线程安全
-
使用 synchronized 可以防止数据不一致问题,但也可能引起线程阻塞,从而影响性能。因此,在使用时应尽量锁定尽可能少的代码块,确保程序效率