博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java锁学习(二)
阅读量:6801 次
发布时间:2019-06-26

本文共 4798 字,大约阅读时间需要 15 分钟。

hot3.png

类锁

类锁 !!!! java类有很多对象 ,但是只有一个class对象 !!!!

所以,类锁,就是针对当前类的Class对象的锁

类锁同一时刻只能被一个对象获取

  1. synchronized放在static方法上(静态锁)
  2. synchronized放在class对象上

静态锁

class SyncClassStatic implements Runnable {    @Override    public void run() {        method();    }    public static synchronized void method() {        System.out.println("我是类锁中静态锁");        try{            Thread.sleep(3000);        }catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"运行结束");    }}result:我是类锁中静态锁Thread-6运行结束我是类锁中静态锁Thread-7运行结束类锁,静态锁运行完毕

class对象锁

class SyncClassObj implements Runnable{    @Override    public void run() {        method();    }    private void method(){        synchronized (SyncClassObj.class) {            System.out.println("我是类锁中class对象锁");            try{                Thread.sleep(3000);            }catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName()+"运行结束");        }    }}result:我是类锁中class对象锁Thread-8运行结束我是类锁中class对象锁Thread-9运行结束类锁,class对象运行完毕

常见场景和问题

  1. 两个线程同时访问一个对象的同步方法会怎样?

    依次执行(锁住的是同一个对象)

  2. 两个线程访问的是两个对象的同步方法又会怎样?

    随机执行(锁住的是不同的对象)

  3. 两个线程访问的是synchronized的静态方法会怎样?

    依次执行(锁住的是同一个类)

  4. 同时访问同步方法与非同步方法会怎样?

    只锁加了synchronized的方法,其他方法不会收到影响

class SyncObjLock implements Runnable {    @Override    public void run() {        if(Thread.currentThread().getName().equals("Thread-0")) {            syncMethod();        }else{            asyncMethod();        }    }    private synchronized void syncMethod()    {        System.out.println("我被锁了");        try{            Thread.sleep(3000);        }catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"运行结束");    }    private void asyncMethod()    {        System.out.println("我没被锁");        try{            Thread.sleep(3000);        }catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"运行结束");    }}同时开始,同时结束:我被锁了我没被锁Thread-0运行结束Thread-1运行结束
  1. 访问同一个对象的不同的普通同步方法会怎样?
class SyncDiff implements Runnable{    @Override    public void run() {        if(Thread.currentThread().getName().equals("Thread-0")) {            syncMethod1();        }else{            syncMethod2();        }    }    private synchronized void syncMethod1()    {        System.out.println("我被锁了,我是方法1");        try{            Thread.sleep(3000);        }catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"运行结束");    }    private synchronized void syncMethod2()    {        System.out.println("我被锁了,我是方法2");        try{            Thread.sleep(3000);        }catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"运行结束");    }}同时开始,同时结束:我被锁了我没被锁Thread-0运行结束Thread-1运行结束
  1. 同时访问静态sync和非静态sync方法
class SyncStaticOrNo implements Runnable {    @Override    public void run() {        if(Thread.currentThread().getName().equals("Thread-0")) {            syncMethod1();        }else{            syncMethod2();        }    }    private synchronized void syncMethod1()    {        System.out.println("我被对象锁");        try{            Thread.sleep(3000);        }catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"运行结束");    }    private static synchronized void syncMethod2()    {        System.out.println("我是类锁");        try{            Thread.sleep(3000);        }catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"运行结束");    }}同时开始,同时结束:我被锁了我没被锁Thread-0运行结束Thread-1运行结束
  1. 方法抛出异常后,会释放锁吗?

会,jvm帮我们释放了

class SyncExc implements Runnable{    @Override    public void run() {            method1();    }    private synchronized void method1()    {        System.out.println(Thread.currentThread().getName()+"开始");        try{            Thread.sleep(3000);        }catch (Exception e) {            e.printStackTrace();        }        throw new RuntimeException("");//        System.out.println("运行结束");    }}
Thread-0开始Exception in thread "Thread-0" java.lang.RuntimeException: 	at Thread.SyncExc.method1(SynchronizedObject.java:187)	at Thread.SyncExc.run(SynchronizedObject.java:176)	at java.lang.Thread.run(Thread.java:748)Thread-1开始Exception in thread "Thread-1" java.lang.RuntimeException: 	at Thread.SyncExc.method1(SynchronizedObject.java:187)	at Thread.SyncExc.run(SynchronizedObject.java:176)	at java.lang.Thread.run(Thread.java:748)

锁的使用场景及分析

整个系统全局同步用类锁,局部锁用对象锁

对比下,就像一样,锁的范围越大,性能自然越低(粒度:类锁>对象锁 性能:类锁<对象锁)

转载于:https://my.oschina.net/lwl1989/blog/3049584

你可能感兴趣的文章
WSL 编程环境配置
查看>>
Reveal配置及上架前配置
查看>>
MySQL可使用GRANT和REVOKE的权限设置
查看>>
iOS应用架构谈 好文
查看>>
Hexo 搭建个人博客
查看>>
Java多态对象的类型转换
查看>>
N*M网格中两对角有多少种不同的路径?(递归)
查看>>
迷宫出逃
查看>>
据说这样可以改变谷歌浏览器的滚动条的样式
查看>>
使用 db2diag 工具来分析 db2diag 日志文件
查看>>
Ubuntu 13.04 64位运行32位程序出现问题
查看>>
promise(then、catch、resolve、reject、race、all、done、finally)
查看>>
Ubuntu 下 配置 jdk1.7
查看>>
思维提升:思维广度,深度,高度,远度
查看>>
服务器空指针不打印堆栈信息解决方法
查看>>
《Linux 系列》- VM上安装CentOS7
查看>>
Python 学习笔记 - socketserver源代码剖析
查看>>
ubuntu关于Java环境变量的 简单记录
查看>>
go的方法
查看>>
最新前端开发面试题
查看>>