java多线程设计模式——学习笔记(2)Single Threaded Execution Pattern
来源:互联网 发布:nba林书豪成名战数据 编辑:程序博客网 时间:2024/05/16 11:46
Single Threaded Execution Pattern是多线程中最为简单的一种模式,其用来限制同时只能让一个线程运行,用于多个线程共享资源(sharedResource)的情况。
文章中举了一个例子来说明该模式的使用。程序模拟3个人频繁经过只能同时通过一个人的门,当人通过门时,程序会在计数器中递增通过人数,并记录通过人员的姓名和地址。
程序中使用的类如下表所示:
名称解说Main创建一个门,并操作三个人不断的穿越门的类Gate表示门的类,当人经过时会记录人的姓名和地址UserThread表示人的类,只负责处理不断的在门间穿越首先是不使用Single Threaded Execution Pattern的情况:
Main类:
public class Main { public static void main(String[] args) { System.out.println("Testing Gate, hit 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(); }}
非线程安全(Thread-safe)的Gate类:
public class Gate { private int counter = 0; private String name = "Nobody"; private String address = "Nowhere"; public void pass(String name, String address) { this.counter++; this.name = name; this.address = address; check(); } public String toString() { return "No." + counter + ": " + name + ", " + address; } private void check() { if (name.charAt(0) != address.charAt(0)) { System.out.println("***** BROKEN ***** " + toString()); } }}其中check()方法是来检测门的状态的,如果姓名和地址的首字母不一致,则表示记录有问题,打印出BROKEN。
UserThread类:
package com.hik.test;public class UserThread extends Thread { private final Gate gate; private final String myname; private final String myaddress; public UserThread(Gate gate, String myname, String myaddress) { this.gate = gate; this.myname = myname; this.myaddress = myaddress; } public void run() { System.out.println(myname + " BEGIN"); while (true) { gate.pass(myname, myaddress); } }}
运行结果:
**** BROKEN ***** No.654810203: Alice, Alaska
***** BROKEN ***** No.654810878: Chris, Canada
***** BROKEN ***** No.654811529: Chris, Alaska
***** BROKEN ***** No.654802550: Bobby, Canada
***** BROKEN ***** No.654812495: Alice, Brazil
***** BROKEN ***** No.654811529: Chris, Alaska
***** BROKEN ***** No.654813485: Chris, Canada
***** BROKEN ***** No.654814227: Alice, Alaska
***** BROKEN ***** No.654814972: Alice, Alaska
***** BROKEN ***** No.654815613: Alice, Alaska
可以看到,运算结果出现了错误,一种情况是即使姓名和地址的首字母一致,但还是打印出了BROKEN,另一种情况就是姓名和地址的首字母不一致的情况。
为什么会出现这种情况?
因为pass方法可以同时被多个线程调用,多个线程调用pass方法时,里面的语句可能是交错运行的,这就有可能出现姓名和地址的首字母不一致的情况。情况有可能如下图所示:
因为,所有线程都是调用同一个pass方法,它们之间是共享的关系,为了避免上述情况的发生,就必须保证同一时间只能有一个线程在访问pass方法。因此,可以将Gate类改为线程安全的类:
public class Gate { private int counter = 0; private String name = "Nobody"; private String address = "Nowhere"; public synchronized void pass(String name, String address) { this.counter++; this.name = name; this.address = address; check(); } public synchronized String toString() { return "No." + counter + ": " + name + ", " + address; } private void check() { if (name.charAt(0) != address.charAt(0)) { System.out.println("***** BROKEN ***** " + toString()); } }}
先来看下运行结果:
Testing Gate, hit CTRL+C to exit.
Alice BEGIN
Bobby BEGIN
Chris BEGIN
(无论等多久,都不会打印出BROKEN)
运行结果正确。通过比较两个Gate类,可以发现,线程安全的Gate类只改了一点点,就是在pass()方法和toString()方法前面加上了synchronized关键字,因为synchronized方法可以保证同一时间只有一个线程可以执行它。
这样我们就完成了一个Single Threaded Execution Pattern。当然这过程中我们还需要注意几点:
- 死锁
- java多线程设计模式——学习笔记(2)Single Threaded Execution Pattern
- 多线程模式之-single Threaded Execution Pattern
- 【Java学习笔记】17:Single Threaded Execution Pattern
- Single Threaded Execution----java多线程设计模式(一)
- 多线程学习系列 - 1 - Single Threaded Execution Pattern
- 多线程设计模式(一) Single Threaded Execution
- Single Threaded Execution Pattern
- java多线程设计模式笔记之Single Thread Execution
- 线程之旅--Single Threaded Execution Pattern
- Java中的线程(八)- Single Threaded Execution模式
- Java线程之Single Threaded Execution Pattern的思维导图
- 第一章 Single Threaded Execution
- Java多线程设计模式详解学习笔记八——Read-Write Lock Pattern
- Multi-threaded design patterns -- Single Threaded Execution
- java多线程设计模式笔记之Future Pattern
- Java设计模式学习—外观模式(Facade Pattern)
- 设计模式学习笔记(2)——装饰模式(Decorator Pattern)
- java多线程设计模式之Immutable Pattern
- txt文件导入数据库,出现file not found错误。
- 写给fourinone的用户
- mysql 字符串连接
- throw()使用小结
- 点类派生直线类(修改)
- java多线程设计模式——学习笔记(2)Single Threaded Execution Pattern
- C++函数后面的throw()
- 【转】linux shell -- 块注释
- Linux下PCI转串口卡驱动安装方法
- 分辨率常识
- 一些编程上的策略
- ASCII 编码
- POJ 2392
- const char *string() const怎么解释?为什么有两个const