使用Boolean类型同步锁引起异常的分析
原文地址 http://topic.csdn.net/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());
-
}
-
}
-
}
输出结果为
当作为同步锁的对象发生改变时,比如换了一个新的对象,那么如果在新的对象上调用同步的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>
使用Boolean类型同步锁引起异常的分析的更多相关文章
- Lock同步锁--线程同步
Lock-同步锁 Lock是java5提供的一个强大的线程同步机制--通过显示定义同步锁对象来实现同步.Lock可以显示的加锁.解锁.每次只能有一个线程对lock对象加锁. Lock有ReadLock ...
- 线程同步 synchronized 同步代码块 同步方法 同步锁
一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...
- python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型
一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...
- Java同步锁——lock与synchronized 的区别【转】
在网上看来很多关于同步锁的博文,记录下来方便以后阅读 一.Lock和synchronized有以下几点不同: 1)Lock是一个接口,而synchronized是Java中的关键字,synchroni ...
- 并发,同步锁,Runnable,Callable,Future
1.并发: 在我们的操作系统中,同一个时间点,有N个线程都想访问同一个程序!但是cpu只能运行一个! 这种情况就是! 多个线程在 同一个时间点 访问同一个资源,会引发线程不安全的问题! 怎么解决这种不 ...
- 结合 Redis 实现同步锁
1.技术方案 1.1.redis的基本命令 1)SETNX命令(SET if Not eXists) 语法:SETNX key value 功能:当且仅当 key 不存在,将 key 的值设为 val ...
- Java同步锁全息详解
一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...
- python开发进程:互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型
一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...
- Java多线程系列 基础篇06 synchronized(同步锁)
转载 http://www.cnblogs.com/paddix/ 作者:liuxiaopeng http://www.infoq.com/cn/articles/java-se-16-synchro ...
随机推荐
- 分析器错误消息: 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分
关于错误提示:此实现不是 Windows 平台 FIPS 验证的加密算法的一部分的解决方案 不知怎么的,每次Win10升级后相应的注册器都恢复默认了,当我运行08版的asp项目时会报这个错. vs上的 ...
- js面向对象1----了解构造函数
一.构造函数与实例的区别 1 构造函数 构造函数主要是一种用于生成对象的饼干模具,这些对象具有默认属性和属性方法,它可以创建多个共享特定特性和行为的对象. 构造函数只是一个函数,但当函数遇到了ne ...
- 微信支付v2开发(7) 告警通知
本文介绍微信支付中如何获得告警通知. 一.告警通知 为了及时通知商户异常,提高商户在微信平台的服务质量.微信后台会向商户推送告警通知,包括发货延迟.调用失败.通知失败等情况,通知的地址是商户在申请支付 ...
- Loadrunner--Analysis网页细分图
续LR实战之Discuz开源论坛项目,之前一直是创建虚拟用户脚本(Virtual User Generator)和场景(Controller),现在,终于到了LoadRunner性能测试结果分析(An ...
- 常用到的Linux命令
记录一下日常用到的Linux命令,就当做日志了 1.查看Linux 端口号 netstat -apn | grep 80 2.杀死进程 kill -s 9 pid (tomcat 启动不起来有可 ...
- 低成本开始互联网创业:探讨域名、服务器、CDN、邮箱等节流之道
互联网创业一直是个热门话题,对这个问题我也有不断的思考. 今天,探讨下如何低成本开始互联网创业. 背景 愿意冒险去创业的同志,大多是"屌丝"而非"高富帅",大多 ...
- 【Codeforces Round #443 (Div. 2) C】Short Program
[链接] 我是链接,点我呀:) [题意] 给你一个n行的只和位运算有关的程序. 让你写一个不超过5行的等价程序. 使得对于每个输入,它们的输出都是一样的. [题解] 先假设x=1023,y=0; 即每 ...
- 【】maze
[链接]点击打开链接 [题意] 小 T 被放到了一个迷宫之中,这个迷宫由 n 个节点构成,两个节点之间可能存在多条无 向边,小 T 的起点为 1 号节点,终点为 n 号节点.有 m 条无向边,对于每一 ...
- springboot入门(三)-- springboot集成mybatis及mybatis generator工具使用
前言 mybatis是一个半自动化的orm框架,所谓半自动化就是mybaitis只支持数据库查出的数据映射到pojo类上,而实体到数据库的映射需要自己编写sql语句实现,相较于hibernate这种完 ...
- 【Struts2三】拦截器
拦截器:就是在訪问action之前.对其进行拦截!能够在拦截器中做一些逻辑的处理! 比方权限验证.没有权限就不给予訪问! 拦截器等效于servlet中的过滤器! 使用拦截器步骤: 1.定义自己的拦截器 ...