使用Boolean类型同步锁引起异常的分析

Java并发学习笔记(二)——Synchronized关键字与ReetrantLock同步锁 一、Synchronized 1、概念 synchronized保证被修饰的方法或代码块操作的原子性、可见性和有序性。synchronized可重入锁、不可中断,适合线程竞争不激烈。 被Synchronized 关键字描述的方法或代码块在多线程环境下同一时间只能由一个线程进行访问,因为在持有当前锁的线程执行完成之前,其他线程想要调用相关方法就必须进行排队,直到当前线程执行完成才释放锁给其他线程,所以保证了原子性。 被Synchronized 关键字描述的方法或代码块在多线程环境下数据是同步的,即当获取到锁后先将内存复制到自己的缓存中操作,释放锁之前会把缓存中的数据复制到共享内存中,所以保证了可 立即下载

原文地址 http://topic.youkuaiyun.com/u/20080710/19/f61cb4db-ddff-4457-a26a-4ea578b0cc6c.html?87447500 http://www.java2000.net/viewthread.jsp?tid=7085

提问:【tteesstt】

public class MyTest {
  public static void main(String[] args) throws Exception {
    new TestThread().start();
    new TestThread().start();
    Thread.sleep(1000);
    System.out.println("Doing something...");
    synchronized (lock) {
      lock = false; // 语句1
      lock.notifyAll(); // 语句2
    }
  }
  static volatile Boolean lock = true;
}

class TestThread extends Thread {
  @Override
  public void run() {
    synchronized (MyTest.lock) {
      while (MyTest.lock) {
        try {
          MyTest.lock.wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println(getId());
    }
  }
}
输出结果为
Doing something...
Exception in thread " main " java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at MyTest.test(MyTest.java: 13 )
at MyTest.main(MyTest.java: 3
如果把语句1和语句2调换一下就正常了。 大家给诊断一下,到底是为什么?
讨论过程请大家自行参考原始的帖子和我的整理帖子,这里只给出最终的分析结果
分析:
当作为同步锁的对象发生改变时,比如换了一个新的对象,那么如果在新的对象上调用同步的wait等方法,由于并没有同步这个对象,而是同步的改变以前的那个,就会报出如上的异常。 我们来看代码
    synchronized (lock) {
      lock = false; // 语句1
      lock.notifyAll(); // 语句2
    }

语句1那里修改了lock的对象指向,结果造成下面的一句notifyAll使用了一个并没有synchronized的对象,随意报出了异常。

解决方法

方案1,使用Boolean的特殊性 由于 lock=false;的特殊性,分析Boolean的源代码发现

    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);
    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

    //发现其内部对于自动打包,拆包只使用了2个固定的对象。所以可以用

    synchronized (lock) {
      lock = false; // 语句1
      Boolean.TRUE.notifyAll(); // 语句2
    }

    // 直接使用那个TRUE就行了。

方法2:使用一个参数可变对象,而不是不可变的,

比如

class MyLock {

   boolean lock = true;

  }

 static volatile MyLock lock = new MyLock();

  // 然后再代码里面用  

lock.lock=false;// 进行标志的变更和判断就可以了

 

结论:

同步锁最好单独使用,如果锁自身附带了其它作用,应使用一个可变的对象 推荐

static volatile MyLock lock = new MyLock();
应该写成
final static volatile MyLock lock = new MyLock();






<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
为什么PCB设计中的50Ω阻抗如此重要?从USB到以太网的实战解析 本文深入解析了PCB设计中50Ω特征阻抗的核心重要性及其工程权衡起源。文章从传输线理论出发,阐释了阻抗匹配对防止信号反射、确保信号完整性的关键作用,并对比了USB、以太网等不同应用场景的阻抗标准。同时,文章结合实际案例,剖析了在两层板等简单设计中实现精准阻抗控制的难点与实战解决方案。 阅读详情

相关推荐

智能网联汽车电子电气架构(下)

从资产的表现形式, 可以分为数据、 软件、 硬件、 服务等, 而从需要保护的业务过程和活动、 所关注信息的角度, 资产类型可包括基于 ECU 的控制功能、 与特定车辆相关的信息、 车辆状态信息、 用户信息、 配置信息、 特定的软件、 内容等。面向新一代 EEA 的安全需求, 基于芯片提供的 OTP, 或SHE\HSM 的安全存储能力, 实现系统关键数据(身份、 密钥等关键信息) 的安全存储, 保证系统的关键数据不被盗取、 破坏、 改写。结合攻击者的动机与识别出的系统用例, 分析对汽车电子系统可能的攻击。

m0_58838529的博客 1473

java synchronized boolean_使用Boolean类型同步锁引起异常的分析

publicclassMyTest{publicstaticvoidmain(String[]args)throwsException{newTestThread().start();newTestThread().start();Thread.sleep(1000);System.out.println("Doingsomething...");synchronized(lock){l...

weixin_32820131的博客 919

解锁医疗AI密码:医疗人工智能专业大学四年学习路径

医疗AI人才培养路径解析 本文系统梳理了医疗人工智能专业四年培养方案,分为基础、进阶、应用和拓展四个阶段: 大一聚焦基础学科,涵盖高等数学、医学概论、Python编程等核心课程,辅以医学数据认知实习。大二深入机器学习和医学数据处理领域,学习监督/无监督学习算法及医学影像分析技术。大三进入深度学习阶段,掌握CNN/RNN等神经网络模型,并实践医疗AI应用开发。大四关注前沿技术如大模型在医疗中的应用,完成毕业设计与企业实习。 课程体系强调医工交叉,每学期均配置实践环节,从基础编程到参与真实医疗AI项目,逐步培养

AllenLV的博客 2504

java中boolean可以作为锁吗_浅谈Java多线程编程中Boolean常量的同步问题

浅谈Java多线程编程中Boolean常量的同步问题发布于 2020-7-22|复制链接摘记: 在JAVA中通过synchronized语句可以实现多线程并发。使用同步代码块,JVM保证同一时间只有一个线程可以拥有某一对象的锁。锁机制实现了多个线程安全地对临界资源进行访问。同步代码写法如下:代码1:```javaObject obj = new Object();...synchr ..在JAVA...

weixin_42525343的博客 2096

Codex登录要手机验证码?Cockpit Tools跳过验证保姆级教程

摘要:OpenAI升级风控后,Codex登录需手机验证,增加批量账号使用成本。CockpitTools(GitHub 8.3k star)可绕过验证,支持多AI编程平台账号管理。操作步骤:1) 获取ChatGPT网页Session数据;2) 通过转换工具生成CPA格式JSON;3) 导入工具启动Codex。注意:仅适用于未绑定手机号的账号,Session会过期,且需防范数据泄露风险。商业账号通常直接提供认证文件。(150字)

5871

Flink实战案例(十三):Flink DataStream 八大分区策略与自定义分区器

声明:本系列博客是根据SGG的视频整理而成,非常适合大家入门学习。 《2021年最新版大数据面试题全面开启更新》 分区策略决定了一条数据如何发送给下游。Flink中默认提供了八大分区策略(也叫分区器)。 本文基于Flink 1.9.0总结Flink DataStream中的八大分区策略以及手动实现一个自定义分区器。 八大分区策略继承关系图 ChannelSelector: 接口,决定将记录写入哪个Channel。有3个方法: void setup(int numberOfChannels):

微信搜:import_bigdata,大数据领域硬核原创作者 1125

JAVA多线程学习5:自己实现一个boolean锁

一个简单的锁 提供一个禁戒值,表示当前锁占用情况。 定义一个lock接口 package com.puqiuyu.thread.blog; /** * 简单实现下就行 * @author sunday * */ public interface Lock { void lock() throws InterruptedException; void unlock()...

ThreadPool_only的博客 858

WPF+MVVM案例实战(一)- 设备状态LED灯变化实现

采用WPF+MVVM框架实现,MVVM框架使用CommunityToolkit.Mvvm 依赖包,代码案例部署了三个LED灯,按照红黄绿三色后台自动刷新状态进行变化,根据后台数据不同,UI层显示不同颜色。

lingshuangcanxue 1382

【详解】Java多线程之自定义Boolean锁&捕获线程中的异常

目录一、 自定义显示锁二、 捕获线程中的异常 一、 自定义显示锁 需求: 设置一个锁,让只有一个线程可以工作,其他的线程阻塞 可以查看都有哪些线程阻塞 只用加锁的线程才可以释放锁,其他线程不允许修改 先定义一个接口,定义锁的规范 public interface Lock { void lock() throws InterruptedException; void un...

xzzz2020的博客 692

三相五柱式消弧线圈自动测控装置设计与实现

本文设计了一种基于STM32的三相五柱式消弧线圈自动测控装置。该装置采用信号注入法检测系统对地电容电流,通过PID自适应算法调节消弧线圈电感值,实现单相接地故障时的快速补偿。硬件系统包含信号采集、注入、控制执行等模块,软件采用Goertzel算法提取特征频率信号,结合增量式PID实现精确控制。实验结果表明,装置电容检测误差小于2%,调谐响应时间小于50ms,满足配电网对消弧线圈自动调谐的技术要求。

AI的内部世界的博客 239

Python爬虫实战:构建药监局药品批准信息本地查询系统

在医药信息化时代,药品批准信息的快速查询对于医药从业者、研究人员和普通消费者都具有重要意义。国家药品监督管理局(NMPA)提供了官方的药品查询系统,但有时我们需要建立本地数据库以便批量分析或离线查询。本文将详细介绍如何使用Python爬虫技术,结合最新的异步爬虫框架和技术栈,构建一个完整的药监局药品信息本地查询系统。本系统将实现以下功能:自动化爬取药监局官网的药品批准信息数据清洗和结构化存储建立本地查询接口数据定期更新机制pythonimport os"""药品类型枚举"""

2201_76125261的博客 729

java知识

##代码 JIT中设置热点代码阈值的参数是? -XX:CompileThreshold=500 修改JIT编译阈值为500 需要GC的区域:Java堆和方法区。 main方法依次往后执行,执行到new的时候才会去进行类加载 Runtime.exec()方法与相关联的ProcessBuilder.start()方法可以用来调用外部程序进程,这些外部程序运行时Process对象会产生哪些流 A 错误流 B 监控流 C 输出流 D 输入流 哪些是同步的? A. TreeSet B. H

未来与一生 2607

华为OD新系统机试真题-勇攀数字高峰(Java/Py/C/C++/Js/Go)

新系统 华为OD机试新系统【勇登数字高峰】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD新系统机试真题【勇登数字高峰】

qq_45776114的博客 1551

java 汇总_java基础汇总

1.关于Http和Hibernatet里面Session的区别HttpSessionHttpSession:是一个抽象接口,J2EE的Web程序在运行的时候,会给每一个新的访问者建立一个HttpSession,这个Session是用户身份的唯一标示,WEB会话跟踪用的。【注:是容器(Tomca)自动创建的】HttpSession用途:存放用户的一些经常被用到的信息,如:用户名,权限。HttpSe...

weixin_39559277的博客 90

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

java基础汇总

1.关于Http和Hibernatet里面Session的区别HttpSession HttpSession:是一个抽象接口,J2EE的Web程序在运行的时候,会给每一个新的访问者建立一个HttpSession,这个Session是用户身份的唯一标示,WEB 会话跟踪用的。【注:是容器(Tomca)自动创建的】 HttpSession用途:存放用户的一些经常被用到的信息,如:用...

weixin_30451709的博客 64

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

为什么boolean类型变量不推荐使用is开头

背景: 平时工作中大家经常使用到boolean以及Boolean类型的数据,前者是基本数据类型,后者是包装类,为什么不推荐使用isXXX来命名呢?到底是用基本类型的数据好呢还是用包装类好呢? 例子: 1.其他非boolean类型 private String isHot; public String getIsHot() { return isHot; } 2.b...

Apple_Boy的博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

JSONObject解析Boolean类型出现异常

Eclipse里面自动生成get和set方法时,以下两种情况生成的get和set方法一样: 情况一:public class Student { private boolean isRight; public boolean isRight() { return isRight; } public void setRight(boolean isRight) { this.isRig

Tender的博客 1万+

Java中的boolean与Boolean

Java中boolean与Boolean的区别:boolean是基本类型,Boolean是其包装类。主要差异包括: boolean不能为null,默认false;Boolean可为null Boolean支持泛型,如List<Boolean> 自动装箱拆箱可能引发NPE Boolean占用更多内存(约16字节) 在Redis锁示例中,不能直接返回setIfAbsent结果,因为可能返回null导致NPE。推荐使用Boolean.TRUE.equals()或BooleanUtil.isTrue()

tuokuac的博客 1330

为什么BAT强制 boolean 类型变量不能使用 is 开头?

一、背景 平时工作中大家经常使用到boolean以及Boolean类型的数据,前者是基本数据类型,后者是包装类,这2种写法随处可见,到底哪种是对的呢,不对的,到底会在哪里翻车?为什么不推荐使用isXXX来命名呢?到底是用基本类型的数据好呢还是用包装类好呢?看了BAT的开发手册后,我给大家捋一下。 二、举例子 1、其他非boolean类型 private String isHot; public String getIsHot() { return isHot; } 2、boolean类型 private

Colin的笔记,也与你共享 571

Flink-Connector-ClickHouse中Boolean类型处理问题的分析与解决

在使用Flink-Connector-ClickHouse进行数据读写时,开发者遇到了一个关于Boolean类型处理的异常问题。当尝试向ClickHouse写入包含Boolean类型列的数据时,系统抛出ClassCastException异常,提示无法将java.lang.Boolean强制转换为java.lang.Number。 ## 问题根源分析 深入分析问题根源,我们发现这与ClickH...

gitblog_07577的博客 448

阿里规范:为什么boolean类型变量命名禁用is开头

java中,对于非boolean类型的参数,getter和setter方法命名的规范是以get和set开头,如下: private String Success; public String getSuccess() { return Success; } public void setSuccess(String success) { Success = success; } 而对...

hungteshun的专栏 2万+

关于Boolean类型做为同步锁异常问题

public class Test2 { private static volatile Boolean aBoolean = true; static class A implements Runnable{ @Override public void run() { synchronized (aBoolean){ ...

//Case 1805
上一篇: 判断数字是否为double的正则表达式
下一篇: Java内部类的分析和整理
老紫竹
博客等级 码龄19年 1万+粉丝 1252原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值