synchronized锁应用场景

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

修饰静态方法(锁当前类):对当前类的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锁(方法锁, 代码块锁)

猜你喜欢

转载自blog.csdn.net/yzx3105/article/details/129858900