一个同步打印机的实现
2010-05-19 14:00
246 查看
文件转自:http://abruzzi.javaeye.com/blog/266317
内部机制
打印机内部设有缓冲区,当有新任务来到的时候,打印机只是简单的从任务中取出需要打印的消息,然后将其存入自身的缓冲区,然后返回,具体的打印任务交给一个线程来处理,打印线程从缓冲区中读消息,打印,然后等待,直到有别的线程唤醒它。其结构如图所示:
单例模式
作为一个系统硬件的模拟,在一个项目中有一个打印机就够用了,在项目中任何需要打印消息的地方,需要使用SyncPrinter.getInstance()
静态方法获取此刻的SyncPrinter实例,并使用print(String message)进行打印。(关于单例模式的细节可以参考别的设计模式的书籍)
同步打印
当然,打印的线程不需要等待打印机缓慢的打印结束,另一种做法是:当打印机收到打印任务后,将此任务放入自己的缓冲区,然后迅速返回,调用打印机的线程可以立即开始接下来的动作,而同时,打印机可以另起一个线程,来打印存储在自己缓冲区中的数据,从而做到同步打印。
缓冲区在本例中实现为一个队列(一个先进先出的数据结构FIFO),队列中的数据总是从尾部插入,从头部被取出。
实现
小结
这个打印机的意义或许不是很大,但是让快速的线程等待一个缓慢的IO过程是不合理的,同时,这是一种分工的思想,而这种互不干涉,各司其职的做法正是面向对象的核心。
借此文来对面向对象的设计原则做一个巩固,同时也可能会帮助其他需要使用同步打印机的人。
内部机制
打印机内部设有缓冲区,当有新任务来到的时候,打印机只是简单的从任务中取出需要打印的消息,然后将其存入自身的缓冲区,然后返回,具体的打印任务交给一个线程来处理,打印线程从缓冲区中读消息,打印,然后等待,直到有别的线程唤醒它。其结构如图所示:
单例模式
作为一个系统硬件的模拟,在一个项目中有一个打印机就够用了,在项目中任何需要打印消息的地方,需要使用SyncPrinter.getInstance()
静态方法获取此刻的SyncPrinter实例,并使用print(String message)进行打印。(关于单例模式的细节可以参考别的设计模式的书籍)
同步打印
当然,打印的线程不需要等待打印机缓慢的打印结束,另一种做法是:当打印机收到打印任务后,将此任务放入自己的缓冲区,然后迅速返回,调用打印机的线程可以立即开始接下来的动作,而同时,打印机可以另起一个线程,来打印存储在自己缓冲区中的数据,从而做到同步打印。
缓冲区在本例中实现为一个队列(一个先进先出的数据结构FIFO),队列中的数据总是从尾部插入,从头部被取出。
实现
import java.util.LinkedList; import java.util.List; public class SyncPrinter { private static SyncPrinter instance; private List msgQueue; private PrintWorker printWorker; public static SyncPrinter getInstance(){//单例模式,任何时候系统中只有一个类实例 synchronized(SyncPrinter.class){ if(instance == null){ instance = new SyncPrinter(); } } return instance; } private SyncPrinter(){ msgQueue = new LinkedList(); printWorker = new PrintWorker(); printWorker.start(); } public void print(String message){// 对外公开的使用打印机的接口 synchronized(msgQueue){ msgQueue.add(message); msgQueue.notify(); } } private class PrintWorker extends Thread{//一个执行打印任务的内部类的封装 private boolean loop = true; private Object lock = new Object(); public void stopPrinter(){ } public void run(){ while(loop){ String msg = ""; synchronized(msgQueue){ try { msgQueue.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // IO msg = (String)msgQueue.remove(0); if(msg != null){ System.out.println(msg); } } } }// 对于这个死循环的控制可以做在外部,也可以做在这个类中,通过一个方法来控制,如stopPrinter() }
小结
这个打印机的意义或许不是很大,但是让快速的线程等待一个缓慢的IO过程是不合理的,同时,这是一种分工的思想,而这种互不干涉,各司其职的做法正是面向对象的核心。
借此文来对面向对象的设计原则做一个巩固,同时也可能会帮助其他需要使用同步打印机的人。
相关文章推荐
- Java中有几种方法实现一个线程,用什么关键字修饰同步方法?stop()和suspend()方法为何不提倡使用?
- 一个免除同步开销的Singleton模式 实现
- java有几种方法可以实现一个线程?用什么关键字修饰同步方法?
- java中有几种方法可以实现一个线程?用什么关键字修饰同步
- 实现一个同步的RenderApplication
- Qt线程同步一个生产者多个消费者的实现
- 实现一个同步的迭代型TCP服务器
- 实现一个同步的并发型TCP服务器
- java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用
- java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
- java基础问题---java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用
- 使用Promise和async-await实现的一个异步遍历+同步执行任务的实例
- 如何实现多个线程写、一个线程读的队列,并且所有线程间不需要等待同步
- 桌上有一空盘,最多允许存放一只水果。爸爸只向盘中放一个苹果,妈妈只向盘中放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。用wait、signal操作实现爸爸、妈妈、儿子、女儿四个并发进程的同步。
- 多个生产者-一个消费者-进程间同步的例子 - OutputDebugString的实现
- 一个简单的BitTorrent客户端实现(三):同步事件分离器
- 一个简单的 python 实现 图片同步脚本 ,对于有图片群集的项目有参考价值
- 实现同步与互斥的一个实例--生产者消费模型
- Java多线程之~~~使用CountDownLatch来同步多个线程实现一个任务
- 【Java面试题】23 java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?