我们都知道当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。这些基础也许大家都知道,但是很多人还是搞不清哪个对象才是锁?如果你能正确回答以下问题,那么才算你彻底搞明白了哪个对象才是锁?

静态同步方法问题

如下代码是两个静态同步方法:

Class A{

public static synchronized void write(boolean b){
isTrue = b;
} public static synchronized boolean read(){
return isTrue;
}
}

那么我们来问几个问题:

  1. 线程1访问A.write(true)方法时,线程2能访问A.read()方法吗?
  2. 线程1访问new A().write(false)方法时,线程2能访问new A().read()方法吗?
  3. 线程1访问A.write(false)方法时,线程2能访问new A().read()方法吗?

实例同步方法问题

如下代码是两个实例同步方法:

public synchronized void write(boolean b){
isTrue = b;
} public synchronized boolean read(){
return isTrue;
}

同样问两个问题:

  1. A a=new A(); 线程1访问a.write(false)方法,线程2能访问a.read()方法吗?
  2. A a=new A(); A b=new A();线程1访问a.write(false)方法,线程2能访问b.read()方法吗?

答案

我们先回顾基础知识,Java中的每一个对象都可以作为锁,而不同的场景锁是不一样的。

  1. 对于实例同步方法,锁是当前实例对象。
  2. 对于静态同步方法,锁是当前对象的Class对象。
  3. 对于同步方法块,锁是Synchonized括号里配置的对象。

线程1访问A.write()方法时,线程2能访问A.read()方法吗?不能,因为静态方法的锁都是A.Class对象,线程1拿到锁之后,线程2就拿不到锁了。

线程1访问new A().write()方法时,线程2能访问new A().read()方法吗?不能,原因同上。

线程1访问A.write()方法时,线程2能访问new A().read()方法吗?不能,原因同上

A a=new A(); 线程1访问a.write()方法,线程2能访问a.read()方法吗?不能,因为这两个方法的锁都是对象a,线程1拿到了锁,线程2就不能访问了。

A a=new A(); A b=new A();线程1访问a.write()方法,线程2能访问b.read()方法吗?可以,因为线程1拿到的是锁是 a,而线程2访问b.read()需要的是锁是b。

转载自并发编程网 – ifeve.com本文链接地址: 哪个对象才是锁?

Java代码中谁拿到了锁?的更多相关文章

  1. Spring MVC框架下在java代码中访问applicationContext.xml文件中配置的文件(可以用于读取配置文件内容)

    <bean id="propertyConfigurer" class="com.****.framework.core.SpringPropertiesUtil& ...

  2. 使用mongo-java-driver3.0.2.jar和mongodb3.0在java代码中的用户验证4

    以下是使用mongo-java-driver3.0.2.jar和mongodb3.0.4在java代码中的用户验证: ServerAddress sa = new ServerAddress(host ...

  3. Android color(颜色) 在XML文件和java代码中

    Android color(颜色) 在XML文件和java代码中,有需要的朋友可以参考下. 1.使用Color类的常量,如: int color = Color.BLUE;//创建一个蓝色 是使用An ...

  4. 关于在Java代码中写Sql语句需要注意的问题

    最近做程序,时不时需要自己去手动将sql语句直接写入到Java代码中,写入sql语句时,需要注意几个小问题. 先看我之前写的几句简单的sql语句,自以为没有问题,但是编译直接报错. String st ...

  5. java代码中获取进程process id(转)

    另一方面,线程ID=进程ID+内部线程对象ID并不成立,    参考: blog.csdn.net/heyetina/article/details/6633901     如何在java代码中获取进 ...

  6. android中在java代码中设置Button按钮的背景颜色

    android中在java代码中设置Button按钮的背景颜色 1.设置背景图片,图片来源于drawable: flightInfoPanel.setBackgroundDrawable(getRes ...

  7. Java代码中获取Json的key值

    测试json字符串: {"access_token":"hkbQl5o_l67dZ7_vJRATKBwTLk9Yj5QyMuOJThAr8Baj0xWf4wxW1p4ym ...

  8. 在java代码中执行js脚本,实现计算出字符串“(1+2)*(1+3)”的结果

            今天在公司项目中,发现一个计算运费的妙招.由于运费规则各种各样,因此写一个公式存到数据库.下次需要计算运费时,直接取出这个公式,把公式的未知变量给替换掉,然后计算出结果就是ok了. 一 ...

  9. 在java代码中,用xslt处理xml文件

    http://blog.csdn.net/zhou_lei/article/details/2661735 ********************************************** ...

随机推荐

  1. HTML3/CSS基础

    1. HTML 1.1 什么是HTML HTML是用来制作网页的标记语言 HTML是Hypertext Markup Language的英文缩写,即超文本标记语言 HTML语言是一种标记语言,不需要编 ...

  2. centos下安装docker,kubelet kubeadm kubectl

    目录 安装docker 安装命令 安装 kubelet kubeadm kubectl 安装命令 安装docker 安装命令 yum install docker -y 启动 systemctl en ...

  3. c++的重载 缺省参数和命名空间详解

    参加了几次笔试,发现有很多c++方面的问题被卡了.从现在开始进攻c++.之后会陆续更新c++学习笔记. 先说说我学习的书籍,大家如果有好的书籍推荐,感谢留言. 暂时是在看这些书自学. 1.C++介绍. ...

  4. eclipse—Maven项目打包成exe

    1.下载打包工具j2ewiz  友情连接:https://pan.baidu.com/s/1Rcoqix5QcrJVI1of9h7qbQ提取码:vqn1 2.选中想要打包的文件,右击—Export 按 ...

  5. Linux入门基础(六):Linux系统启动

    系统启动流程 BIOS MBR : Boot Code 执行引导程序-GRUB 加载内核 执行init runlevel BIOS BIOS(basic input output system),我们 ...

  6. Intellij IDEA创建maven项目无java文件问题

    在idea开发工具中创建工程时,点击右键没有创建包.接口.java类的提示, 如图: 解决之前的项目目录为: 针对这种情况,对idea开发工具做以下设置. 选择File->Project Str ...

  7. Netty源码分析第2章(NioEventLoop)---->第8节: 执行任务队列

      Netty源码分析第二章: NioEventLoop   第八节: 执行任务队列 继续回到NioEventLoop的run()方法: protected void run() { for (;;) ...

  8. Cocos2dx源码赏析(2)之渲染

    Cocos2dx源码赏析(2)之渲染 这篇,继续从源码的角度来跟踪下Cocos2dx引擎的渲染过程,以此来梳理下Cocos2dx引擎是如何将精灵等元素显示在屏幕上的. 从上一篇对Cocos2dx启动流 ...

  9. reduce()用法

    reduce()方法接受一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终为一个值 参数 callback 执行数组中的每个值的函数,包含四个参数 previousValue 上一次调用回调 ...

  10. 【Alpha】技术规格说明书

    由于第1周已经写过技术规格说明书(设计文档),本周更新了上一版内容. Github地址:https://github.com/buaase/Phylab-Web/blob/master/docs/Ba ...