博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java中的类锁和对象锁对比分析
阅读量:2348 次
发布时间:2019-05-10

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

      说到锁机制,不得不提到Thread线程,而又不得不提到synchronized关键字,这个单词的意思是表示“同步”的意思。用它去修饰方法函数的时候,如果有多个线程同时调用这个方法函数的时候,那么当一个线程获得锁的时候,其他的线程只能进入等待队列,直到这根线程执行完毕,释放锁的时候,其他线程才可以获得锁去执行这个方法函数。

       这里我们主要讲的是对象锁和类锁。对象锁,顾名思义,即为对象级别的锁,一个对象一个锁,不论为这个对象创建多少个线程。类锁,同样的意思,即为类级别的锁,一个类一个锁,这个类的所有对象共有一个锁。这两个锁在形式上的区别是类锁会有一个static关键字修饰。

       下面来看看具体的例子,先定义一个具有对象锁和类锁的Demo类:

package com.Jevin.thread;public class Demo {    //对象锁:    public synchronized void test01(){        try {            System.out.println(Thread.currentThread().getName());            Thread.sleep(3000);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    //类锁:    public static synchronized void test02(){        try {            System.out.println(Thread.currentThread().getName());            Thread.sleep(3000);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

      我们先创建一个对象两个线程去调用对象锁,观察一下执行情况:

package com.Jevin.thread;public class ObjectLock {    public static void main(String[] args){        //定义一个对象:        Demo d=new Demo();        //创建线程对象:        Thread t1=new Thread(new Runnable() {            @Override            public void run() {                d.test01();            }        },"t1");        Thread t2=new Thread(new Runnable() {            @Override            public void run() {                d.test01();            }        },"t2");        //启动线程:        t1.start();        t2.start();    }}

        执行情况:线程t1先执行,过了3秒钟后,线程t2再开始执行。那为什么呢?我的看法是:我们只创建了一个Demo对象,这个在堆中的对象包含了我们的对象锁的test01方法,两个线程进入同步块中,符合线程的执行规律。

         那么,我们创建两个对象,会发生什么现象呢?如下所示:

package com.Jevin.thread;public class ObjectLock {    public static void main(String[] args){        //定义一个对象:        Demo d1=new Demo();        Demo d2=new Demo();        //创建线程对象:        Thread t1=new Thread(new Runnable() {            @Override            public void run() {                d1.test01();            }        },"t1");        Thread t2=new Thread(new Runnable() {            @Override            public void run() {                d2.test01();            }        },"t2");        //启动线程:        t1.start();        t2.start();    }}

       执行结果是:t1线程和t2线程同时执行,我的看法是:我们创建了两个对象,这两个对象各拥有自己的test01方法函数,线程t1中的t1引用调用自己堆中的对象的test01方法,线程t2中的引用t2调用自己堆中的test01方法,各自互不影响,所以不会出现线程等待那种情况。

      那么,问题来了,我去调用有static关键字修饰的test02方法,会怎样呢?答案是,不论一个对象,还是两个对象,或是n个对象,都会出先线程等待,线程一个一个的调用,为什么呢?我觉得:有static关键字修饰的方法,已经从对象级别上升到类级别了,所以,不论多少对象,都共有这个方法,所以才出现这种不论多少对象都会线程等待的现象。

转载地址:http://nrtvb.baihongyu.com/

你可能感兴趣的文章
后台管理系统之商品管理
查看>>
Elasticsearch配置和使用
查看>>
基于Spring Data Elasticsearch的搜索微服务
查看>>
Chrome的“请停用以开发者模式运行的扩展程序”提示【彻底解决】_多种方式总有适合你的
查看>>
商品详情及Thymeleaf静态化
查看>>
如何安装最纯净的Windows系统,玩转重装操作系统
查看>>
RabbitMQ安装使用及数据同步
查看>>
用户中心
查看>>
授权中心
查看>>
乐优商城—购物车
查看>>
乐优商城—订单微服务
查看>>
《剑指offer》思路与实现总结--Java
查看>>
字符串数组转成矩阵
查看>>
贪心算法 and 动态规划
查看>>
Java主流锁
查看>>
在Intellij IDEA中使用Debug详解
查看>>
BAT面试总结
查看>>
基于SSM的后台管理系统总结
查看>>
注册谷歌邮箱?
查看>>
freenom免费域名申请及设置域名解析
查看>>