Single Thread Execution 能通过这座桥的只有一个人
直奔主题, Single Thread Execution也称作Critical Section(临界区),范例如下:
public class SingleThreadGate {
public static void main(String[] args) {
System.out.println("ctrl + c to exit."); Gate gate = new Gate();
new UserThread(gate, "Alice", "Alaska").start();
new UserThread(gate, "Bobby", "Brazil").start();
new UserThread(gate, "Chris", "Canada").start();
}
} class Gate{
private int count;
private String name;
private String address; public void pass(String name, String address){
this.count++;
this.name=name;
this.address=address; check();
} public void check() {
if (name.charAt(0) != address.charAt(0)) {
System.out.println("*******BROKEN *******" + toString());
}
} @Override
public String toString() {
return "No." + count + " " + name + ", " + address;
} } class UserThread extends Thread{
private Gate gate;
private String name;
private String address; public UserThread(Gate gate, String name, String address){
this.gate=gate;
this.name=name;
this.address=address;
} @Override
public void run() {
System.out.println(name+":begin->");
while(true){
gate.pass(name,address);
Thread.yield();
}
}
}
执行之后,会发现ou一很多broken,因为在执行pass的时候成员变量被其他线程改变了,所以判断name和address不一致,另外toString方法也存在同样的问题,执行过程中 name和address也随时被其他线程改变,所以会导致同一条记录的name和address也不一致,结果如下:
ctrl + c to exit.
Alice:begin->
Chris:begin->
Bobby:begin->
*******BROKEN *******No. Bobby, Brazil
*******BROKEN *******No. Chris, Canada
*******BROKEN *******No. Bobby, Brazil
*******BROKEN *******No. Bobby, Brazil
*******BROKEN *******No. Alice, Canada
*******BROKEN *******No. Chris, Alaska
*******BROKEN *******No. Alice, Canada
*******BROKEN *******No. Bobby, Brazil
*******BROKEN *******No. Chris, Alaska
*******BROKEN *******No. Bobby, Brazil
*******BROKEN *******No. Chris, Alaska
*******BROKEN *******No. Bobby, Brazil
那么如何改进呢?将pass方法加上synchronized关键字,这样就不会有任何错误了。不过这还不能保证整个gate类的所有方法都是安全的,当调用toString方法时还是会有同样的name与address不一致的问题,所以在toString方法上也要加上synchronized关键字,那么check方法还需要么?答案是不需要,因为check方法时私有的,外部无法访问,而且check方法是被pass方法调用的,而pass方法已经同步了,一个类中的synchronized关键之都是锁定的同一对象(this),所以不需要二次锁定,浪费性能。
synchnronized关键字也可以理解成把方法变成原子性操作,在java中,基本数据类型(primitive)如int, char, byte等都是原子性操作的,但是long和double则不一定,所以我们想把long和double这类非原子性类型按照原子性方式操作,需要加上关键字volatile,这样就可以了。
Single Thread Execution 能通过这座桥的只有一个人的更多相关文章
- 多线程系列之二:Single Thread Execution 模式
一,什么是SingleThreadExecution模式?同一时间内只能让一个线程执行处理 二,例子 1.不安全的情况 用程序模拟 三个人频繁地通过一个只允许一个人经过的门.当人通过时,统计人数便会增 ...
- Single Thread Execution设计模式
public class Test { public static void main(String[] args){ // FlightSercurityTest.test(); // EatNoo ...
- 多线程设计模式(一) Single Threaded Execution
这里有一座独木桥.因为桥身非常的细,一次只能允许一个人通过.当这个人没有下桥,另一个人就不能过桥.如果桥上同时又两个人,桥就会因为无法承重而破碎而掉落河里. 这就是Single Threaded Ex ...
- 多线程程序设计学习(2)之single threaded execution pattern
Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResourc ...
- JAVA并发设计模式学习笔记(二)—— Single Threaded Execution Pattern
注:本文的主要参考资料为结城浩所著<JAVA多线程设计模式>. 单线程执行模式(Single Threaded Execution Pattern)是最简单的多线程设计模式,几乎所有其他的 ...
- 多线程学习之一独木桥模式Single Threaded Execution Pattern
Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResourc ...
- How does a single thread handle asynchronous code in JavaScript?
原文:https://www.quora.com/How-does-a-single-thread-handle-asynchronous-code-in-JavaScript ----------- ...
- Current thread must be set to single thread apartment (STA) mode before OLE,当前线程不在单线程单元中,因此无法实例化 ActiveX 控件“8856f961-340a-11d0-a96b-00c04fd705a2”。
Add the STAThreadAttribute attribute on the Main method. This attribute is required if your program ...
- C# Current thread must be set to single thread apartment (STA) mode before OLE calls can be made
将箭头指向部分替换为编译器报错的内容即可. 参考文章:https://www.experts-exchange.com/questions/28238490/C-help-needed-Current ...
随机推荐
- 【Codeforces Round #429 (Div. 2) B】 Godsend
[Link]:http://codeforces.com/contest/841/problem/B [Description] 两个人轮流对一个数组玩游戏,第一个人可以把连续的一段为奇数的拿走,第二 ...
- NX二次开发-UFUN特征找xxx UF_MODL_ask_feat_xxx等函数(待补充)
NX9+VS2012 #include <uf.h> #include <uf_modl.h> #include <uf_obj.h> #include <u ...
- 2018-06-05(thinking in java)
1:类只能有2种访问权限,一种是不写访问权限:默认包访问权限,另一种是public.且类只能有一个pubic 2:方法有4种访问权限,pubic(都可以访问),protexted(继承访问权限),pr ...
- BZOJ随即跳题-随即到什么题你写什么题
来挑战一下吧~ 请事先登录你BZOJ的账号!
- 基于Netty的RPC架构学习笔记(五):netty线程模型源码分析(二)
文章目录 小技巧(如何看开源框架的源码) 源码解析 阅读源码技巧 打印查看 通过打断点调试 查看调用栈 小技巧(如何看开源框架的源码) 一断点 二打印 三看调用栈 四搜索 源码解析 //设置nioso ...
- LeetCode刷题笔记-BFS-二叉树层次遍历
题目描述: 给定一个二叉树,返回其节点值自底向上的层次遍历. (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如:给定二叉树 [3,9,20,null,null,15,7], 3 / \ ...
- Codeforces 1167D - Bicolored RBS
题目链接:http://codeforces.com/problemset/problem/1167/D 题意:题目定义RBS,给你一个字符串,你要对其所有字符染色,使之分解为俩个RBS,使俩个RBS ...
- [14]APUE:API for Mysql
库:/usr/lib64/libmysqlclient.so.#.#... 头文件:/usr/lib64/mysql/mysql.h 一.建立连接 MYSQL *mysql_init(MYSQL *) ...
- 【POJ】3278 Catch That Cow
题目链接:http://poj.org/problem?id=3278 题意:有一头奶牛跑到了K的位置,农夫在N的位置,求最短抓到奶牛的时间. 农夫有两种移动方式. 1.步行:一分钟内从x->x ...
- iOS开发系列-NSDate
NSDate API 获取当前时间 获取时间戳 创建间隔指定时间戳的Date // 获取昨天 NSTimeInterval time = 24 * 60 * 60; NSDate *date = [N ...