正确运用synchronized和二次判断 实现多线程安全
正确运用synchronized和二次判断 实现多线程安全,做出高效二符合预期的程序,特别是多个线程跑一个对象的时候,如下图所示: 
测试代码如下:
特别注意if(shutdownRequested){ *部分不同的写法。
不然就会输出与逻辑不符的现象:
如:
runner—-false—-我没有关闭。。。
runner—-true—-我没有关闭。。。
runner—-true—-我关闭了=====»>
package com.xue.gang.volatiler;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class VolatileRunner{
public static void main(String args[]) throws InterruptedException {
int size=1000;
CountDownLatch countDownLatch = new CountDownLatch(size);
TomRunner tomRunner = new TomRunner(false,countDownLatch,"runner");
ExecutorService executorService = Executors.newCachedThreadPool();
for(int i=1;i<=size;i++){
executorService.execute(new Thread2RunTomRunner(countDownLatch,tomRunner,i+"_号"));
}
countDownLatch.await();
executorService.shutdown();
//new Thread(volatileRunner).start();
}
static class Thread2RunTomRunner implements Runnable{
private CountDownLatch countDownLatch;
private TomRunner tomRunner;
private String name;
public Thread2RunTomRunner(CountDownLatch countDownLatch,
TomRunner tomRunner, String name) {
super();
this.countDownLatch = countDownLatch;
this.tomRunner = tomRunner;
this.name = name;
}
public void run() {
System.out.println(this.name+":running...");
this.tomRunner.doWork();
System.out.println(this.name+":结束...");
this.countDownLatch.countDown();
}
}
static class TomRunner{
volatile boolean shutdownRequested = false;
//boolean shutdownRequested = false;
String name;
public TomRunner(boolean shutdownRequested,
CountDownLatch countDownLatch, String name) {
super();
this.shutdownRequested = shutdownRequested;
this.name = name;
}
public void shutdown() {
this.shutdownRequested = true;
}
public void doWork() {
while (true) {
/**
*多个线程的代码去执行: System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我没有关闭。。。");
* */
/*if(shutdownRequested){
System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我关闭了=====>>>");
break;
}else{
System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我没有关闭。。。");
shutdown();
}*/
/**
* 如果没有二次判断,也会出现比较脏数据.
* */
/*
if(shutdownRequested){
System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我关闭了=====>>>");
break;
}
synchronized (this) {
System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我没有关闭。。。");
shutdown();
}*/
/**
* 加上二次判断,能够正确
* */
if(shutdownRequested){
System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我关闭了=====>>>");
break;
}
synchronized (this) {
if(!shutdownRequested){
System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我没有关闭。。。");
shutdown();
}
}
}
}
}
}
原:http://my.oschina.net/u/177808/blog/165442
正确运用synchronized和二次判断 实现多线程安全的更多相关文章
- python3.4学习笔记(二) 类型判断,异常处理,终止程序
python3.4学习笔记(二) 类型判断,异常处理,终止程序,实例代码: #idle中按F5可以运行代码 #引入外部模块 import xxx #random模块,randint(开始数,结束数) ...
- Java问题记录——循环里的二次判断与状态更新
Java问题记录——循环里的二次判断与状态更新 摘要:本文主要记录了在循环操作时可能出现的问题. 问题重现 在使用循环结构时,如果使用了定时任务,或者代码会多次调用循环结构,可能会导致有些对象会被循环 ...
- Synchronized之二:synchronized的实现原理
Java提供了synchronized关键字来支持内在锁.Synchronized关键字可以放在方法的前面.对象的前面.类的前面. 当线程调用同步方法时,它自动获得这个方法所在对象的内在锁,并且方法返 ...
- python--基础学习(二)判断 、循环、定义函数、继承、调用
1.判断 if.elif 代码示范 # coding=utf-8 score = 90 if (score>=90): print("完美") print("优秀& ...
- bash脚本编程之二 条件判断and 逻辑运算
1.条件测试结构 1) if/then结构: 判断命令列表的退出码是否为0,0为成功. 如果if和then在条件判断的同一行上的话, 必须使用分号来结束if表达式: if和then都是关键字. 关键字 ...
- python语法(二)— 判断
昨天简单的学习了一些python的一些简单的语句与python的数据类型,今天继续学习python的基础语句 if 语句. 一.if 语句 if 语句语法 if expression: ifSuite ...
- JAVA Synchronized (二)
一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...
- 并发编程之synchronized(二)------jvm对synchronized的优化
一.锁的粗化 看如下代码 public class Test { StringBuffer stb = new StringBuffer(); public void test1(){ //jvm的优 ...
- 5-3 bash脚本编程之二 条件判断
1. 条件测试的表达式 1. [ expression ] :注意这个中括号的前后都有一个空格 2. [[ expression ]] 3. test expression 2.条件判断的类型 1. ...
随机推荐
- 【USACO 1.5】Prime Palindromes
/* TASK: pprime LANG: C++ SOLVE: 枚举数的长度,dfs出对称的数,判断是否在范围内,是否是素数 原来想着枚举每个范围里的数,但是显然超时,范围最大是10^9. 对称的数 ...
- 匿名内部类为什么访问外部类局部变量必须是final的?
1.内部类里面使用外部类的局部变量时,其实就是内部类的对象在使用它,内部类对象生命周期中都可能调用它,而内部类试图访问外部方法中的局部变量时,外部方法的局部变量很可能已经不存在了,那么就得延续其生命, ...
- AFnetworking3.1的基本使用
听说之后AFHttpWorking版本可能会影响到苹果的审核,今天下了最新版本的AFHttpWorking,并且做了简单的封装,我这里是通过cocoapods下载了两个工具 1=AFHttpWorki ...
- C++强制类型转换操作符 static_cast
static_cast是一个强制类型转换操作符.强制类型转换,也称为显式转换,C++中强制类型转换操作符有static_cast.dynamic_cast.const_cast.reinterpert ...
- Leetcode 347. Top K Frequent Elements
Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2 ...
- 【BZOJ-4213】贪吃蛇 有上下界的费用流
4213: 贪吃蛇 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 58 Solved: 24[Submit][Status][Discuss] Desc ...
- 【bzoj1178】 Apio2009—CONVENTION会议中心
http://www.lydsy.com/JudgeOnline/problem.php?id=1178 (题目链接) 题意 给出n个区间,问在区间两两不相交的情况下最多能选出多少区间,并输出字典序最 ...
- 【codevs1086】 栈
http://codevs.cn/problem/1086/ (题目链接) 题意 给出1~n总共n个数,对它们进行入栈出栈操作,问一共有多少种不同的方案. Solution 找规律手玩前5个1 2 5 ...
- BZOJ1049 [HAOI2006]数字序列0
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- 做自己的类库dll文件
除了在项目中把类放在不同的文件夹之外,还可以把他们放在完全不同的项目中,添加引用dll 实现对类的调用, 如果一个项目只包含类 但没有入口点 ,那么这个项目叫做类库. 类库项目编译为.dll程序集.( ...