3.6 Java类锁、对象锁、私有锁、隐式锁


类锁对象锁是否会冲突?对象锁和私有锁是否会冲突?通过实例来进行说明。

一、相关约定

为了明确后文的描述,先对本文涉及到的锁的相关定义作如下约定:

1. 类锁:在代码中的方法上加了static和synchronized的锁,或者synchronized(xxx.class)的代码段,如下文中的increament();

2.对象锁:在代码中的方法上加了synchronized的锁,或者synchronized(this)的代码段,如下文中的synOnMethod()和synInMethod();

3.私有锁:在类内部声明一个私有属性如private Object lock,在需要加锁的代码段synchronized(lock),如下文中的synMethodWithObj()。

二、测试代码

1.编写一个启动类ObjectLock

public class ObjectLock {    public static void main(String[] args) {        System.out.println("start time = " + System.currentTimeMillis()+"ms");        LockTestClass test = new LockTestClass();        for (int i = 0; i < 3; i++) {            Thread thread = new ObjThread(test, i);            thread.start();        }    }}

2.编写一个线程类ObjThread,用于启动同步方法(注意它的run方法可能会调整以进行不同的测试)

public class ObjThread extends Thread {    LockTestClass lock;    int i = 0;     public ObjThread(LockTestClass lock, int i) {        this.lock = lock;        this.i = i;    }     public void run() {        //无锁方法//      lock.noSynMethod(this.getId(),this);        //对象锁方法1,采用synchronized synInMethod的方式        lock.synInMethod();        //对象锁方法2,采用synchronized(this)的方式//      lock.synOnMethod();        //私有锁方法,采用synchronized(object)的方式//      lock.synMethodWithObj();        //类锁方法,采用static synchronized increment的方式        LockTestClass.increment();    }}

3.再编写一个锁的测试类LockTestClass,包括各种加锁方法

public class LockTestClass {    //用于类锁计数    private static int i = 0;    //私有锁    private Object object = new Object();     /**     * &lt;p&gt;     * 无锁方法     *     * @param threadID     * @param thread     */    public void noSynMethod(long threadID, ObjThread thread) {        System.out.println("nosyn: class obj is " + thread + ", threadId is"                + threadID);    }     /**     * 对象锁方法1     */    public synchronized void synOnMethod() {        System.out.println("synOnMethod begins" + ", time = "                + System.currentTimeMillis() + "ms");        try {            Thread.sleep(2000L);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("synOnMethod ends");    }     /**     * 对象锁方法2,采用synchronized (this)来加锁     */    public void synInMethod() {        synchronized (this) {            System.out.println("synInMethod begins" + ", time = "                    + System.currentTimeMillis() + "ms");            try {                Thread.sleep(2000L);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println("synInMethod ends");        }     }     /**     * 对象锁方法3     */    public void synMethodWithObj() {        synchronized (object) {            System.out.println("synMethodWithObj begins" + ", time = "                    + System.currentTimeMillis() + "ms");            try {                Thread.sleep(2000L);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println("synMethodWithObj ends");        }    }     /**     * 类锁     */    public static synchronized void increament() {        System.out.println("class synchronized. i = " + i + ", time = "                + System.currentTimeMillis() + "ms");        i++;        try {            Thread.sleep(2000L);        } catch (InterruptedException e) {            e.printStackTrace();        }         System.out.println("class synchronized ends.");    } }

三、测试结果

  1. 测试类锁和对象锁,ObjectThread的run方法修改如下:

public void run() {        //无锁方法//      lock.noSynMethod(this.getId(),this);        //对象锁方法1,采用synchronized synInMethod的方式        lock.synInMethod();        //对象锁方法2,采用synchronized(this)的方式//      lock.synOnMethod();        //私有锁方法,采用synchronized(object)的方式//      lock.synMethodWithObj();        //类锁方法,采用static synchronized increment的方式        LockTestClass.increament();    }

终端输出:

start time = 1413101360231ms synInMethod begins, time = 1413101360233ms synInMethod ends class synchronized. i = 0, time = 1413101362233ms synInMethod begins, time = 1413101362233ms  class synchronized ends.  synInMethod ends  class synchronized. i = 1, time = 1413101364233ms  synInMethod begins, time = 1413101364233ms  class synchronized ends.  synInMethod ends  class synchronized. i = 2, time = 1413101366234ms  class synchronized ends.

可以看到对象锁方法(synInMothod)第一次启动时比类锁方法(increament)快2秒,这是因为在synInMehtod执行时 sleep了2秒再执行的increament,而这两个方法共用一个线程,所以会慢2秒,如果increament在run中放到 synInMethod前面,那么第一次启动时就是increament快2秒。

而当类锁方法启动时,另一个线程时的对象锁方法也几乎同时启动,说明二者使用的并非同一个锁,不会产生竞争。

结论:类锁和对象锁不会产生竞争,二者的加锁方法不会相互影响。

2.私有锁和对象锁,ObjectThread的run方法修改如下:

public void run() {        //无锁方法//      lock.noSynMethod(this.getId(),this);        //对象锁方法1,采用synchronized synInMethod的方式        lock.synInMethod();        //对象锁方法2,采用synchronized(this)的方式//      lock.synOnMethod();        //私有锁方法,采用synchronized(object)的方式        lock.synMethodWithObj();        //类锁方法,采用static synchronized increment的方式//      LockTestClass.increament();    }

终端输出:

start time = 1413121912406ms synInMethod begins, time = 1413121912407ms. synInMethod ends. synMethodWithObj begins, time = 1413121914407ms synInMethod begins, time = 1413121914407ms. synInMethod ends. synMethodWithObj ends synInMethod begins, time = 1413121916407ms. synMethodWithObj begins, time = 1413121916407ms synInMethod ends. synMethodWithObj ends synMethodWithObj begins, time = 1413121918407ms synMethodWithObj ends

和类锁和对象锁非常类似。

结论:私有锁和对象锁也不会产生竞争,二者的加锁方法不会相互影响。

3.synchronized直接加在方法上和synchronized(this),ObjectThread的run方法修改如下:

public void run() {  //无锁方法 // lock.noSynMethod(this.getId(),this);  //对象锁方法1,采用synchronized synInMethod的方式  lock.synInMethod();  //对象锁方法2,采用synchronized(this)的方式  lock.synOnMethod();  //私有锁方法,采用synchronized(object)的方式  // lock.synMethodWithObj();  //类锁方法,采用static synchronized increment的方式  // LockTestClass.increament(); }

终端输出:

start time = 1413102913278ms synInMethod begins, time = 1413102913279ms synInMethod ends synInMethod begins, time = 1413102915279ms synInMethod ends synOnMethod begins, time = 1413102917279ms synOnMethod ends synInMethod begins, time = 1413102919279ms synInMethod ends synOnMethod begins, time = 1413102921279ms synOnMethod ends synOnMethod begins, time = 1413102923279ms synOnMethod ends

可以看到,二者严格地串行输出(当然再次执行时先运行synInMethod还是先运行synOnMethod并不是确定的,取决于谁获得了锁)。

结论:synchronized直接加在方法上和synchronized(this)都是对当前对象加锁,二者的加锁方法够成了竞争关系,同一时刻只能有一个方法能执行。

Java 类锁、对象锁、私有锁相关推荐

  1. 从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的?

    转载自   从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的? 先回顾一下Java程序执行的过程: Java程序执行时,第一步系统创建虚拟机进程,然后虚拟器用类加载器Class Loade ...

  2. 实验2 Java类和对象的设计

    实验题目:Java类和对象的设计 一.上机目的和要求 理解面向对象的编程思想.类与对象的概念: 加深理解封装性.继承性和多态性: 掌握this.super.final.static等关键字的使用: 掌 ...

  3. java类与对象实验_JAVA类与对象实验报告

    <JAVA类与对象实验报告>由会员分享,可在线阅读,更多相关<JAVA类与对象实验报告(6页珍藏版)>请在人人文库网上搜索. 1.面向对象程序设计实验报告实验三.类与对象(1) ...

  4. 杨校老师课堂之Java类与对象、封装、构造方法

    杨校老师课堂之Java类与对象.封装.构造方法 本篇文章内容如下: 面向对象 类与对象 三大特征--封装 构造方法 教学目标 能够理解面向对象的思想 能够明确类与对象关系 能够掌握类的定义格式 能够掌 ...

  5. java类和对象程序_Java类与对象程序设计基础

    Java类与对象程序设计基础 一.实验目的: 通过编制一个独立应用程序,使得学生掌握Java的系统所提供类的引用方法:通过编制一个完整的应用程序,使得学生对Java的应用程序的基本构成和基本算法熟练掌 ...

  6. java类与对象 演练 查找并修改姓名

    java类与对象 演练 查找并修改姓名 视频 https://www.ixigua.com/i6870489659168784903/ 思路 先定义一个类 类中有一个名字数组 提前给这个数组一些默认值 ...

  7. java类与对象 演练 客户姓名添加与查看

    java类与对象 演练 客户姓名添加与查看 视频 https://www.ixigua.com/6870483106223096327?logTag=_YUmIb2rn9-6JpoNipj9r 类的定 ...

  8. 最大公约数与最小公倍数( 初学Java 类与对象 )

    最大公约数与最小公倍数( java 类与对象的运用 ) Problem Description 输入两个正整数,求它们的最大公约数与最小公倍数. Input 输入两个正整数,两个整数之间用空格分开. ...

  9. Java类和对象(如何理解类和对象)

    Java类和对象 一.什么是对象? 1.什么是对象的属性? 2.什么是对象的行为 二.什么是类? 三. 类和对象的关系 四.类的定义 1.类的定义格式 2.类的定义示例 五.对象的使用 1.对象的创建 ...

  10. 【Java类和对象】

    Java类和对象 在Java简介中就有介绍到,Java是一门面向对象的编程语言,在面向对象的编程语言中,肯定离不开对象这个概念,而对象则是类的实例,所以也肯定离不开类这个概念.简单的来说就是,在Jav ...

最新文章

  1. 盖尔-沙普利算法_盖尔定律-及其与初创企业的关系
  2. 推荐15个实用强大的网站,每一个都让人惊艳
  3. 杭电1754--I Hate It(线段树)
  4. EasyUI的combobox用法
  5. boost::reinterpret_pointer_cast相关的测试程序
  6. ajax拿table里的th值,Jquery Ajax 异步设置Table中某列的值
  7. C++_选择结构_switch语句_循环结构while_while案例猜数字_do while循环_dowhile案例水仙花数_---C++语言工作笔记017
  8. android堆叠效果相册_CSS实现照片堆叠效果
  9. 从零基础入门Tensorflow2.0 ----二、4.1 wide deep 模型(函数式API)
  10. NB-IoT移远BC95调试笔记 01 加网测试
  11. 计算机图形学及CAD技术 微盘,计算机图形学及cad技术讲义——曲线曲面基本理论.pdf...
  12. 基于fabric的行业联盟链技术研究/司帅帅
  13. 非线性方程模型及求解实例
  14. VBS脚本实现宽带上网加网页认证上网双验证
  15. Win10 -- CUDA10 CUDNN 安装
  16. 职场:结果导向的前提是过程控制
  17. windows下tomcat设置开机自启
  18. 教你怎么学好Java
  19. 西门子PLC 硬件标识符 (Hardware ID)基本应用
  20. Word使用心得:邮件合并

热门文章

  1. aws rds恢复数据库_Amazon RDS – AWS关系数据库服务
  2. zookeeper入门学习之java api会话建立《四》
  3. 开课吧:人工智能是后互联时代的发展路径和方向
  4. 前端web:响应式网站开发的现状你了解吗?
  5. JAVA中的枚举使用总结
  6. 开发linux版QQ就是支持未来的国产操作系统
  7. log4net进阶手札(四):保存自定义对象到oracle
  8. form表单file,select选择后自动提交
  9. 【最大连接数】Linux的文件最大连接数
  10. 使用Zabbix中遇到的问题:snmp监控端口流量偶尔会断图