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 ...
随机推荐
- [HL] 7.5 集训总结
对于某唤做赛区难度的题,我只能是内流满面..拿到题,A神题不可做,B,神题不可做,C,神题不可做...最后yy了一个A的算法...只得了20 TAT.C题骗分似乎有50 ..B题本来想骗分..然后/ ...
- Lua的控制流程
一.条件语句 if语句 if语句是由一个布尔表达式作为条件判断,或者紧跟其他语句组成. if else语句 if语句可以是else搭配使用,在if条件表达式为false时执行else语句代码 if嵌套 ...
- ETL详解
ETL是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程,目的是将企业中的分散.零乱.标准不统一的数据整合到一起,为企业的决策提供分析依据. ETL是BI项目重要的一个环节. 通常情况下,在 ...
- NX二次开发-将工程图上的每个视图导出PNG图片
大概思路是将每个视图导出PDF,在调另一个项目的EXE(PDF转PNG) //ExportDrawViewPng // Mandatory UF Includes #include <uf.h& ...
- NX二次开发-创建CSYS坐标系UF_CSYS_create_csys
NX9+VS2012 #include <uf.h> #include <uf_csys.h> #include <uf_mtx.h> UF_initialize( ...
- sqlalchemy之create_engine和session
sqlalchemy之create_engine和session orm 实质上,一个O/R Mapping会为你生成DAL.(即为数据访问层(Data Access Layer).其功能主要是负责数 ...
- java 传入多个参数时报"Parameter 'XXX' not found. Available parameters are [arg1, arg0, param1,..." 解决方案
@Select("SELECT id FROM ae_post ORDER BY id DESC LIMIT #{page},#{size}") List<Post> ...
- STM32---初学者用库函数好还是直接对寄存器操作比较好
引用:http://blog.csdn.net/u010349006/article/details/416 首先,两个都是C语言.从51过渡过来的话,就先说寄存器操作.每个MCU都有自己的寄存器,5 ...
- Guarded Suspention 要等到我准备好
线程在运行过程中需要停下来等待,然后再继续执行. 范例程序,一个线程(ClientThread)对另外一个线程(ServerThread)传递请求,实现一个模拟消息通道的功能. public clas ...
- 2019-9-11-在-P2P-文件分享应用以文件或文件段为单位的优缺
title author date CreateTime categories 在 P2P 文件分享应用以文件或文件段为单位的优缺 lindexi 2019-09-11 10:23:27 +0800 ...