java 静态锁和对象锁

java 静态锁和对象锁

对象锁

java中要实现线程同步,

同一个类中使用 synchronized 关键字在方法上或者代码块中
默认表示使用当前对象的锁
多线程访问时候会进行抢锁,释放锁,通对象的方法执行分先后顺序

以下方法 lock1 lock2 lock3 表示相同的对象锁 lock4 表示的是 成员变量 object 的锁

输出的时候 lock1 lock2 lock3 之中一个和 lock4 几乎同时输出,剩下两个按照顺序输出

先看下面例子
ThisKLock 类中定义四个方法 lock1 lock2 lock3 lock4

首先

启动 线程m1 m2启动发现lock1和lock2 没有同时输出,先后输出。

原因 : 在当前Lock 类中,使用 synchronized 关键字在方法上修饰 , 线程m1 和 m2 回去争抢线程锁,然后等待释放,另一个线程才能执行。

synchronized 用在方法上默认表示 对象

其次

启动 m1 m2 m3 发现 m1 m2 m3 是先后输出来。 这说明三个都是在用同一个对象锁。
而m3中 synchronized (this) 在方法中进行同步,再结合m1 m2 可以看出 都是使用用一个对象锁,结果是等价的都做到的线程同步。

但是 方法上使用synchronized 关键字多个线程情况下 同一个时间大量线程在方法外进行等待,造成堵塞
而在方法内部使用 synchronized 代码块可以小范围的进行代码同步,缩短大量线程等待时间,可以执行的等待之前的任务模块,缩短运行时间。

最后

启动 m1 m4 发现 几乎同时执行出来结果。
而m4中 使用 同步代码块 锁是private final Object object = new Object(); object的锁,与 m1 不是一个对象锁,故不存在争抢锁,等待的情况。


public class ThisKLock {

    public static void main(String[] args) {
        Lock lock = new Lock();

        new Thread("m1") {
            @Override
            public void run() {
                lock.lock1();
            }
        }.start();


        new Thread("m2") {
            @Override
            public void run() {
                lock.lock2();
            }
        }.start();

        new Thread("m3") {
            @Override
            public void run() {
                lock.lock3();
            }
        }.start();


        new Thread("m4") {
            @Override
            public void run() {
                lock.lock4();
            }
        }.start();
    }

}



 
class Lock {


    public synchronized void lock1() {
        try {
            System.out.println(" lock1 ");
            Thread.sleep(10_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public synchronized void lock2() {
        try {
            System.out.println(" lock2 ");
            Thread.sleep(10_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void lock3() {
        synchronized (this) {
            try {
                System.out.println(" lock3 ");
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private final Object object = new Object();


    public void lock4() {
        //使用object对象的锁
        synchronized (object) {
            try {
                System.out.println(" lock4 ");
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

静态锁

定义两个静态方法 lock1 和 lock2

class Lock2 {


    public static synchronized void lock1() {
        try {
            System.out.println(" lock1 ");
            Thread.sleep(10_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static synchronized void lock2() {
        try {
            System.out.println(" lock2 ");
            Thread.sleep(10_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

然后启动两个线程去执行,如果前后输出lock1 lock2来 表示使用的是同一个对象锁
如果同时输出出来表示 使用的不是对象锁,则静态锁。
在这里插入图片描述
可以看到lock1 和 lock2是前后分别输出出来,可以在静态方法上加锁默认是对象锁

然后我们使用synchronized 代码块在静态方法中加锁,当然this关键字是无法使用
那我们怎么加锁呢,答案是字节码class对象,在jvm中class也是对象


    public static void lock3() {
        synchronized (Lock2.class) {
            try {
                System.out.println(" lock3 ");
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

静态代码块加锁

    static {
        synchronized (ThreadStaticLock.class) {
            try {
                System.out.println(" static ");
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

执行 的时候会发现 执行一次且先输出 static 静态语句块优先执行,切使用的是同一个对象锁
此时 this = 字节码 必须等待释放锁之后 lock1 lock2 lock3 才能去争抢锁,然后依次输出。

在这里插入图片描述

发布了241 篇原创文章 · 获赞 66 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/weixin_38361347/article/details/103571573