synchronized锁应用场景

目录标题

  • 方法(静态方法/实例方法)
    • 修饰静态方法(锁当前类):对当前类的Class对象加锁
    • 修饰实例方法(锁当前对象实例):对当前实例对象this加锁
  • 修饰代码块(锁指定对象/类)
    • synchronized(类.class) 表示进入同步代码前要获得 给定 Class 的锁
    • synchronized(object) 表示进入同步代码库前要获得 给定对象的锁。

方法(静态方法/实例方法)

修饰静态方法(锁当前类):对当前类的Class对象加锁

public class SynchronizedDemo {
    // 修饰普通方法(实例方法)
    public synchronized void instanceMethod() {
        // TODO 业务逻辑
    }
 
    public static void main(String[] args) {
        SynchronizedDemo obj1 = new SynchronizedDemo();
        SynchronizedDemo obj2 = new SynchronizedDemo();
        new Thread(() ->{
            obj1.instanceMethod(); //多线程访问加锁普通实例方法,互不影响
        }).start();
        new Thread(() ->{
            obj2.instanceMethod();
        }).start();
    }
}

普通方法作用范围是对象实例,不可跨对象,所以多个线程不同对象实例访问此方法,互不影响,无法产生互斥。

修饰实例方法(锁当前对象实例):对当前实例对象this加锁

public class SynchronizedDemo {
    // 修饰静态方法(类方法)
    public synchronized static void staticMethod() {
        // TODO 业务逻辑
    }
 
    public static void main(String[] args) {
        new Thread(() ->{
            SynchronizedDemo.staticMethod(); //多线程访问加锁静态方法,互斥
        }).start();
        new Thread(() ->{
            SynchronizedDemo.staticMethod();
        }).start();
    }
}

静态方法是通过类访问,是类级别的跨对象的,所以锁的范围是针对类,多个线程访问互斥。

修饰代码块(锁指定对象/类)

synchronized(类.class) 表示进入同步代码前要获得 给定 Class 的锁

public class SynchronizedDemo {
    // 代码块锁(类):锁的应用对象是User类,可以称之为类锁
    public void method2() {
        synchronized (User.class) {
            // TODO 业务逻辑
        }
    }
 
    public static void main(String[] args) {
        SynchronizedDemo obj1 = new SynchronizedDemo();
        SynchronizedDemo obj2 = new SynchronizedDemo();
        new Thread(() ->{
            obj1.method2(); //代码块锁,后面是类,多线程访问互斥
        }).start();
        new Thread(() ->{
            obj2.method2();
        }).start();
}

虽然是通过对象访问的此方法,但是加锁的代码块是类级别的跨对象的,所以锁的范围是针对类,多个线程访问互斥。

synchronized(object) 表示进入同步代码库前要获得 给定对象的锁。

public class SynchronizedDemo {
    // 代码块锁(对象实例):锁的应用对象是当前对象实例,可以称之为对象锁
    public void method1() {
        synchronized (this) {
            // TODO 业务逻辑
        }
    }
 
    public static void main(String[] args) {
        SynchronizedDemo obj1 = new SynchronizedDemo();
        SynchronizedDemo obj2 = new SynchronizedDemo();
        new Thread(() ->{
            obj1.method1(); //代码块锁,后面是对象,多线程访问互不影响
        }).start();
        new Thread(() ->{
            obj2.method1();
        }).start();
    }
}

作用范围是对象实例,不可跨对象,所以多个线程不同对象实例访问此方法,互不影响,无法产生互斥。

demo来源:synchronized锁(方法锁, 代码块锁)

你可能感兴趣的:(面试题-并发,java)