线程的线程同步Synchronize、互斥锁、死锁、释放锁

55 阅读2分钟

线程的线程同步

  1. 在多线程编程,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何同一时刻,最多有一个线程访问,以保证数据的完整性。
  2. 也可以这里理解:线程同步,即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作. synchronized线程同步机制.png

synchronized同步细节

  1. 修饰静态方法,锁的是类
  2. 非静态方法,锁的是当前对象

synchronized同步细节.png

互斥锁.png

互斥锁 | | 同步锁的注意事项与细节

  1. 同步方法如果没有使用static:默认锁对象为this
  2. 如果方法使用static修饰,默认锁对象,:当前类.class

死锁

public class DeadLockDemo {
    public static void main(String[] args) {
        // 模拟死锁
        //模拟死锁现象
        DeadLock A = new DeadLock(true);
        A.setName("A 线程");
        DeadLock B = new DeadLock(false);
        B.setName("B 线程");
        A.start();
        B.start();
    }
}
class DeadLock extends Thread {
    static Object o1 = new Object();
    static Object o2 = new Object();
    boolean flag;
    public DeadLock(boolean flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        if(flag) {
            synchronized (o1) { // 对象互斥锁,下面是同步 代码块
                System.out.println(Thread.currentThread().getName()+"进入1");
                synchronized (o2) {
                    System.out.println(Thread.currentThread().getName()+"进入2");
                }
            }
        }else {
            synchronized (o2) { // 对象互斥锁,下面是同步 代码块
                System.out.println(Thread.currentThread().getName()+"进入3");
                synchronized (o1) {
                    System.out.println(Thread.currentThread().getName()+"进入4");
                }
            }
        }
    }
}

释放锁

  1. 当前线程的同步方、同步代码块执行结束
  2. 当前线程在同步代码块、同步方法中遇到break、return
  3. 当前线程在同步代码块、同步方法中出现了未处理的Error、或者Exception,导致异常结束
  4. 当前线程在同步代码块、同步方法中执行了线程对象的wait()方法,当前线程暂停、并释放锁

释放锁-蹲坑案例.png

什么操作不会释放锁

  1. 线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yiled()方法暂停当前线程的执行,不会释放锁(yield会让线程从运行Running状态切换成Ready就绪状态)
  2. 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁(要尽量避免suspend和resume(恢复)方法来控制线程)