Java多线程设计模式(二)
Guarded Suspension Pattern
- public class Request {
- private Stringname;
- public Request(String name) {
- this.name = name;
- }
- public String getName() {
- returnname;
- }
- @Override
- public String toString() {
- return"[ Request " +name +" ]";
- }
- }
- public class RequestQueue {
- final private LinkedList<request>queue = new LinkedList<request>();
- public synchronizedvoid putRequest(Request request) {
- this.queue.addLast(request);
- notifyAll();
- }
- publicsynchronized Request getRequest() {
- // 多线程版本的if
- while (this.queue.size() <= 0) {
- try {
- wait();
- }catch (InterruptedException e) {
- }
- }
- return queue.removeFirst();
- }
- }
- import java.util.Random;
- public class ClientThreadextends Thread {
- private Random random;
- private RequestQueuerequestQueue;
- public ClientThread(RequestQueue requestQueue, String name,long seed) {
- super(name);
- this.requestQueue = requestQueue;
- this.random =new Random(seed);
- }
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- Request request = new Request("No." + i);
- System.out.println(Thread.currentThread().getName() +" requests " + request);
- this.requestQueue.putRequest(request);
- try {
- Thread.sleep(this.random.nextInt(1000));
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- import java.util.Random;
- public class ServerThreadextends Thread {
- private Random random;
- private RequestQueuequeue;
- public ServerThread(RequestQueue queue, String name,long seed) {
- super(name);
- this.queue = queue;
- random =new Random(seed);
- }
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- Request request = queue.getRequest();
- System.out.println(Thread.currentThread().getName() +" handles " + request);
- try {
- Thread.sleep(random.nextInt(1000));
- } catch (InterruptedException e) {
- }
- }
- }
- }
- public class Main {
- public static void main(String[] args) {
- RequestQueue queue = new RequestQueue();
- ServerThread serverThread = new ServerThread(queue,"ServerThread", 3141592l);
- ClientThread clientThread = new ClientThread(queue,"ClientThread", 6535897l);
- serverThread.start();
- clientThread.start();
- }
- }
- </request></request>
这段代码的关键在 ReqeustQueue类的getReqeust()方法,在该方法中,判断队列是否小于或等于0,如果是,那么就等待队列有数据之后在进行获取 Request对象的操作,注意这里使用的是while,而非if。Single Threaded Execution Pattern 只有一个线程可以进入临界区,其他线程不能进入,进行等待;而Guarded Suspension Pattern中,线程要不要等待,由警戒条件决定。只有RequestQueue类使用到了wait/notifyAll,Guarded Suspension Pattern的实现是封闭在RequestQueue类里的。
Balking Pattern
回,它与Guarded Suspension Pattern的区别在于Guarded Suspension
Pattern在警戒条件不成立时,线程等待,而Balking Pattern线程直接返回。我们来看代码实现:
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- public class Data {
- private final Stringfilename;
- private String content;
- privateboolean changed;
- public Data(String filename, String content) {
- this.filename = filename;
- this.content = content;
- this.changed =true;
- }
- public synchronizedvoid change(String content) {
- this.content = content;
- this.changed =true;
- }
- publicsynchronizedvoid save() {
- while (!this.changed) {
- return;
- }
- doSave();
- this.changed =false;
- }
- private void doSave() {
- System.out.println(Thread.currentThread().getName() +"calls doSave, content = "
- + this.content);
- File file = new File(filename);
- FileWriter writer = null;
- try {
- writer = new FileWriter(file, true);
- writer.write(this.content);
- } catch (IOException e) {
- } finally {
- if (writer !=null) {
- try {
- writer.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
- import java.util.Random;
- public class ChangerThreadextends Thread {
- private Data data;
- private Randomrandom =new Random();
- public ChangerThread(String name, Data data) {
- super(name);
- this.data = data;
- }
- @Override
- public void run() {
- int i = 0;
- while (true) {
- i++;
- String content = "No." + i;
- this.data.change(content);
- try {
- Thread.sleep(random.nextInt(1000));
- } catch (InterruptedException e) {
- }
- this.data.save();
- }
- }
- }
- import java.util.Random;
- public class SaverThreadextends Thread {
- private Data data;
- private Randomrandom =new Random();
- public SaverThread(String name, Data data) {
- super(name);
- this.data = data;
- }
- @Override
- public void run() {
- while (true) {
- this.data.save();
- try {
- Thread.sleep(this.random.nextInt(1000));
- } catch (InterruptedException e) {
- }
- }
- }
- public static void main(String[] args) {
- Data data = new Data("data.txt","(empty)");
- new SaverThread("SaverThread", data).start();
- new ChangerThread("ChangerThread", data).start();
- }
- }
Producer-Consumer Pattern
- import java.io.Serializable;
- public class Data implements Serializable {
- /**
- *
- */
- private static final long serialVersionUID = 7212370995222659529L;
- private String name;
- public Data(String name) {
- this.name = name;
- }
- @Override
- public String toString() {
- return"[ Data name = " +this.name +" ]";
- }
- }
- import java.util.LinkedList;
- /**
- * 数据传输channel,默认大小100,可以通过构造函数定制channel的大小。channel为FIFO模型
- */
- public class Channel {
- private final LinkedList<data>buffer =new LinkedList<data>();
- private int bufferSize = 100;
- public Channel() {
- super();
- }
- public Channel(int channelSize) {
- this.bufferSize = channelSize;
- }
- /**
- * put数据到channel中,当channel的buffer大小大于或等于指定大小时,方法将进行等待
- *
- * @param data
- */
- public synchronizedvoid put(Data data) {
- while (buffer.size() >=this.bufferSize) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
- this.buffer.addLast(data);
- System.out.println(Thread.currentThread().getName() +" put data " + data);
- notifyAll();
- }
- /**
- * 从channel中获取数据,当channel中没有数据时,进行等待
- *
- * @return
- */
- public synchronized Data take() {
- while (this.buffer.size() == 0) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
- Data data = this.buffer.removeFirst();
- System.out.println(Thread.currentThread().getName() +" take date " + data);
- notifyAll();
- return data;
- }
- }
- import java.util.Random;
- public class ComsumerThreadextends Thread {
- private Channel channel;
- private Random random =new Random();
- public ComsumerThread(String name, Channel channel) {
- super(name);
- this.channel = channel;
- }
- @Override
- public void run() {
- while (true) {
- this.channel.take();
- try {
- Thread.sleep(random.nextInt(1000));
- } catch (InterruptedException e) {
- }
- }
- }
- }
- import java.util.Random;
- public class ProducerThreadextends Thread {
- private Channel channel;
- private Random random =new Random();
- private staticintdataNo = 0;
- public ProducerThread(String name, Channel channel) {
- super(name);
- this.channel = channel;
- }
- @Override
- public void run() {
- while (true) {
- Data data = new Data("No." + nextDataNo());
- this.channel.put(data);
- try {
- Thread.sleep(random.nextInt(1000));
- } catch (InterruptedException e) {
- }
- }
- }
- public staticsynchronizedint nextDataNo() {
- return ++dataNo;
- }
- }
- public class MainThread {
- public static void main(String[] args) {
- int channelSize = 1000;
- Channel channel = new Channel(channelSize);
- ProducerThread producer1 = new ProducerThread("Producer1", channel);
- ProducerThread producer2 = new ProducerThread("Producer2", channel);
- ComsumerThread comsumer1 = new ComsumerThread("Comsumer1", channel);
- ComsumerThread comsumer2 = new ComsumerThread("Comsumer2", channel);
- ComsumerThread comsumer3 = new ComsumerThread("Comsumer3", channel);
- producer1.start();
- producer2.start();
- comsumer1.start();
- comsumer2.start();
- comsumer3.start();
- }
- }
- </data></data>
Java多线程设计模式(二)的更多相关文章
- [温故]图解java多线程设计模式(一)
去年看完的<图解java多线程设计模式>,可惜当时没做笔记,导致后来忘了许多东西,打算再温习下这本书,顺便在这里记录一下~ 1.顺序执行.并行.并发 顺序执行:多个操作按照顺序依次执行. ...
- java多线程设计模式
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt220 java多线程设计模式 java语言已经内置了多线程支持,所有实现Ru ...
- Java多线程(二)关于多线程的CPU密集型和IO密集型这件事
点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...
- 简述Java多线程(二)
Java多线程(二) 线程优先级 Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行. 优先级高的不一定先执行,大多数情况是这样的. 优 ...
- Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)
一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会 ...
- java多线程系列(二)
对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...
- java多线程系列(二)---对象变量并发访问
对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...
- Java多线程设计模式(一)
目录(?)[-] Java多线程基础 Thread类的run方法和start方法 线程的启动 线程的暂时停在 线程的共享互斥 线程的协调 Single Threaded Execution Patte ...
- Java多线程设计模式(4)线程池模式
前序: Thread-Per-Message Pattern,是一种对于每个命令或请求,都分配一个线程,由这个线程执行工作.它将“委托消息的一端”和“执行消息的一端”用两个不同的线程来实现.该线程模式 ...
- Java总结篇系列:Java多线程(二)
本文承接上一篇文章<Java总结篇系列:Java多线程(一)>. 四.Java多线程的阻塞状态与线程控制 上文已经提到Java阻塞的几种具体类型.下面分别看下引起Java线程阻塞的主要方法 ...
随机推荐
- ConcurrentHashMap放入null值报错
//ConcurrentHashMap源码: /** Implementation for put and putIfAbsent */ final V putVal(K key, V value, ...
- Tkinter Menubutton(菜单按钮)
Python - Tkinter Menubutton: 一个菜单按钮是一个下拉菜单,在屏幕上停留时间的一部分.菜单的小工具,可以显示该菜单按钮的选择,当用户点击它与每个menubutton时. ...
- django的实现异步机制celery
celery 一句话总结:celery是一种实现异步的机制,对于比较耗时的任务可以使用其来减少客户端等待时间(注册邮箱验证),提高用户体验. 官方网站 中文文档 示例一:用户发起request,并等待 ...
- preprocess
1,宏定义,有参宏,无参宏,宏定义实现的是定义一个符号常量; 条件编译3种方式,文件包含含义; 不带参数的宏定义;既用一个指定的的标识符来代替一个字符串; #define RUIY 10000000 ...
- **python中的类和他的成员
面向对象是一种编程方式,此编程方式的实现基于对 类 和 对象 的使用. Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的. 在这里,为文章中使用 ...
- MantisBT 缺陷管理系统
简介: 公司需要一套缺陷管理系统,这种系统比较热门的有 Jira.Redmine.MantisBT 等. 这次来整理一下 MantisBT,正好公司需要,以前的文档又丢失了. 下载地址:http:// ...
- Java 循环遍历删除set list中的元素
删除List和Set中的某些元素 错误代码的写法: Set<String> set = new HashSet<String>(); set.add("aaaaaa& ...
- centos7+tomcat部署JavaWeb项目超详细步骤
我们平时访问的网站大多都是发布在云服务器上的,比如阿里云.腾讯云等.对于新手,尤其是没有接触过linux系统的人而言是比较有困难的,而且至今使用云服务器也是有成本的,很多时候我们可以通过虚拟机自己搭建 ...
- freeswitch由于ext-sip-ip地址填写错误导致32秒拆线问题
通话32秒左右就断掉 检查 profile 的 ext-sip-ip 设置ext-rtp-ip和ext-sip-ip 可以直接设置为外网IP 自建stun-server, 更新后, 过了好几个小时出现 ...
- svn: Can't connect to host
关于“svn: Can't connect to host '*.*.*.*': 由于连接方在一段时间后没有正确答复或连接”的解决方法 阿里云服务器环境(PHP+Nginx+MySQL) [原因1 ...