synchronized同步机制
什么是Java的线程同步?
在多线程情况下,它通过对关键代码段加锁,针对某个共享资源的访问同时只允许一个线程进行操作,从而避免多个线程同时访问共享资源时引发的数据不一致问题。
三种同步方式:
- synchronized
- ReentrantLock
- JUC
synchronized同步机制:
Java 提供的加锁关键字,用于在方法或代码块上加锁,以确保同一时刻只有一个线程能够执行被同步的方法或代码块。
在 synchronized 可以使用 wait()、notify() 和 notifyAll() 实现条件等待通知
- wait():当前线程进入等待状态,直到被其他线程唤醒。必须在同步块或同步方法中调用
- notify():唤醒一个等待的线程。如果有多个线程在等待,同一时刻只能唤醒一个
- notifyAll():唤醒所有等待的线程
1.synchronized加在实例方法上,锁住的对象是调用方法的实例对象
对象1.increment() <-- 锁住对象1
对象2.increment() <-- 可以同时执行,不影响对象1
2.synchronized加在静态方法上,锁住的是类对象
注意:不同类的实例不会调用同一个静态方法,所以这个关注的是同一个类的实例。
同一个类对象1.increment() <-- 锁住 Counter.class
同一个类对象2.increment() <-- 其他线程必须等待
3.synchronized加在代码块上,可以指定一个特定的对象作为锁,此方法更加灵活
synchronized(lock1) { ... } <-- 锁住 lock1,只影响 lock1 相关的线程
synchronized(lock2) { ... } <-- 锁住 lock2,不影响 lock1
举例:
public class Counter {private int count = 0;// synchronized加在同步实例方法上public synchronized void increment() {count++;}// 同步静态方法public static synchronized void staticIncrement() {// 静态方法的锁是类的 Class 对象}
}public class Counter {
// 创建锁对象private final Object lock = new Object();private int count = 0;public void increment() {// 加在代码块上,指定特定对象为锁synchronized (lock) {count++;}}
}