0

0

Java类锁、对象锁、私有锁冲突测试

高洛峰

高洛峰

发布时间:2017-01-19 13:41:40

|

1542人浏览过

|

来源于php中文网

原创

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

一、相关约定

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

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

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

立即学习Java免费学习笔记(深入)”;

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();
 /**
  * 

* 无锁方法 * * @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();
 }

终端输出:

稿定AI绘图
稿定AI绘图

稿定推出的AI绘画工具

下载
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 = 1413121912412406ms
synInMethod begins, time = 1413121912412407ms.
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类锁、对象锁、私有锁冲突测试相关文章请关注PHP中文网!

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

42

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

4

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号