synchronized对象锁和类锁

发布于:2024-05-11 ⋅ 阅读:(57) ⋅ 点赞:(0)

一、什么是对象锁和类锁

顾名思义 对象锁可以锁住同一对象下synchronized修饰的方法,但不会影响其他对象。synchronized修饰普通方法就为对象锁。

类锁static synchronized修饰一个方法,当一个线程在执行该方法时,其他任何线程用任何对象调用static  synchronized修饰的方法都需要等待。

二、对象锁例子

class Data {
    public synchronized void synchronizedHello() {
        try {
            TimeUnit.MILLISECONDS.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(Thread.currentThread().getName() + "-----hello");
    }
    public synchronized void synchronizedGood(){
        System.out.println(Thread.currentThread().getName() + "-----good");
    }
    public  void nice(){
        System.out.println(Thread.currentThread().getName() + "-----nice");
    }
}
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        Data data = new Data();
        Data data1 = new Data();
        new Thread(data::synchronizedHello, "a").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(data::synchronizedGood, "b").start();
        new Thread(data::nice, "c").start();
        new Thread(data1::synchronizedGood, "d").start();
    }
}

输出结果:

c-----nice
d-----good
a-----hello
b-----good

介绍: 主线程中创建了四个线程分别为a,b,c,d他们分别调用data对象的synchronizedHello,synchronizedGood,nice方法。调用synchronizedHello主线程睡眠0.2秒。

synchronizedHello方法加锁切会使线程睡眠2秒钟

synchronizedGood方法仅加锁

nice方法不加锁

结果分析:c-----nice最先打印说明nice方法不受a线程synchronizedHello方法的睡眠2秒影响,正常异步执行完成。说明对象锁不加synchronized的方法不受锁的影响。

d-----good第二个打印同样不受a线程synchronizedHello方法的睡眠2秒影响。说明对象锁只能锁住自己对象的synchronized修饰的方法。

b-----good最后打印是受到了a线程synchronizedHello方法的睡眠2秒影响。说明synchronized修饰的方法并非独立,会收到其他synchronized修饰的方法的影响。

 三、类锁例子

class Data {
    public static synchronized void synchronizedHello() {
        try {
            TimeUnit.MILLISECONDS.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(Thread.currentThread().getName() + "-----hello");
    }
    public static synchronized void synchronizedGood(){
        System.out.println(Thread.currentThread().getName() + "-----good");
    }
    public  void nice(){
        System.out.println(Thread.currentThread().getName() + "-----nice");
    }
}
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        Data data = new Data();
        Data data1 = new Data();
        new Thread(() -> data.synchronizedHello(), "a").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> data.synchronizedGood(), "b").start();
        new Thread(() -> data1.synchronizedGood(), "d").start();
        new Thread(data::nice, "c").start();
    }
}

输出结果:

c-----nice
a-----hello
d-----good
b-----good

介绍:方法 synchronizedHello,synchronizedGood都加了static修饰

结果分析:先打印c----nice因为nice方法没加锁

d-----good,b-----good在a-----hello后打印说明其他任何线程用任何对象调用static  synchronized修饰的方法都需要等待

如果删除synchronizedGood的static修饰则输出结果为:

b-----good
d-----good
c-----nice
a-----hello

 结果说明:类锁的方法并没有锁住对象锁修饰的方法。

四、结论

对象锁的锁对象是对象本身即this而类锁的锁对象是类名.class索引其不是同一把锁,互不干扰。开发中遇到需要加锁的地方应当尽量使用对象锁而不是类锁。