使用观察者模式实现线程将计算结果回调给多个对象
来源:互联网 发布:酷狗上传的歌网络异常 编辑:程序博客网 时间:2024/06/10 02:27
《Java网络编程》第三章线程讲使用回调的方法从线程中返回信息给对象。例如,如果有多个对象对线程的计算结果感兴趣,那么线程可以保存一个要回调的对象列表。特定的对象可以通过调用线程类的一个方法把自己添加到这个列表中来完成注册,表示自己对计算结果很感兴趣。如果有多个类的实例对结果感兴趣,可以定义一个新的Observer interface (接口),所有这些类都要实现这个新接口。这个Observer interface(接口)将声明回调方法。以上是观察者模式的典型应用场景。
接下来将上面的需求实现。
1. Observer接口
声明回调方法update
interface Observer { void update(byte[] digest);}
2. 感兴趣的观察者InstanceCallbackDigestUserInterface01
其中将通知者作为其成员变量
public class InstanceCallbackDigestUserInterface01 implements Observer { static Logger logger = LoggerFactory.getLogger(InstanceCallbackDigestUserInterface01.class); private String filename; private byte[] digest; public InstanceCallbackDigestUserInterface01(String filename) { this.filename = filename; } @Override public String toString() { String result = filename + ": "; if (digest != null) { result += DatatypeConverter.printHexBinary(digest); } else { result += "digest not available"; } return result; } @Override public void update(byte[] digest) { this.digest = digest; //只是显示摘要,但功能更强的类还可以完成其他操作 //如将摘要存储在一个字段中,用它启动另一个钱程,或者对它完成进一步的计算。 logger.info(this.toString()); }}
3. 感兴趣的观察者InstanceCallbackDigestUserInterface02以及新线程任务SaveDatabase
public class InstanceCallbackDigestUserInterface02 implements Observer { Logger logger = LoggerFactory.getLogger(InstanceCallbackDigestUserInterface02.class); byte[] digest = null; @Override public void update(byte[] digest) { logger.info("interface02 get this digest"); this.digest = digest; ExecutorService exec = Executors.newCachedThreadPool(); exec.submit(new SaveDatabase(digest)); }}class SaveDatabase implements Runnable { Logger logger = LoggerFactory.getLogger(SaveDatabase.class); private byte[] digest; public SaveDatabase(byte[] digest){ this.digest = digest; } @Override public void run() { String s = DatatypeConverter.printHexBinary(digest); logger.info(s); }}
4. 通知者InstanceCallbackDigest
保存一个要回调的对象列表callback。特定的对象可以通过调用attach方法把自己添加到这个列表中来完成注册
public class InstanceCallbackDigest implements Runnable { Logger logger = LoggerFactory.getLogger(InstanceCallbackDigest.class); private String filename; private LinkedHashSet<Observer> callback = new LinkedHashSet<>(); public InstanceCallbackDigest(String filename) { this.filename = filename; } public void attach(Observer observer) { callback.add(observer); } public void detach(Observer observer) { callback.remove(observer); } @Override public void run() { try { FileInputStream in = new FileInputStream(filename); MessageDigest sha = MessageDigest.getInstance("SHA-256"); DigestInputStream din = new DigestInputStream(in, sha); while (din.read() != -1) ; // read entire file din.close(); byte[] digest = sha.digest(); for (Observer o:callback ) { logger.info("callback update"); o.update(digest); } } catch (IOException | NoSuchAlgorithmException ex) { System.err.println(ex); } }}
5. Test类
public class Test { static Logger logger = LoggerFactory.getLogger(Test.class); public void calculateDigest(String filename, LinkedHashSet<Observer> callback) { InstanceCallbackDigest cb = new InstanceCallbackDigest(filename); //注册 for (Observer o : callback ) { cb.attach(o); } Thread t = new Thread(cb); t.start(); } @org.junit.Test public void test () { logger.info("main线程"); String[] strs = new String[]{"bw01.txt","pom.xml"};// String[] strs = new String[]{"bw01.txt"}; for (String filename : strs) { //注册 InstanceCallbackDigestUserInterface01 d = new InstanceCallbackDigestUserInterface01(filename); InstanceCallbackDigestUserInterface02 interface02 = new InstanceCallbackDigestUserInterface02(); LinkedHashSet<Observer> callback = new LinkedHashSet<>(); callback.add(d); callback.add(interface02); //启动了线程 calculateDigest(filename, callback); //如何通知主线程子线程结束? try { TimeUnit.SECONDS.sleep(3l); } catch (InterruptedException e) { e.printStackTrace(); } } }}
6. 类图
7. 运行结果
阅读全文
0 0
- 使用观察者模式实现线程将计算结果回调给多个对象
- 观察者模式使用C#实现
- 使用观察者模式观察线程的生命周期
- JTABLE 一个小格子添加2个按钮实现国际化 使用观察者设计模式
- 使用观察者(Observer)实现对象监听
- 观察者模式使用WebForm实现的例子
- 使用 Java8 架构实现观察者模式
- 使用C++实现OO观察者模式
- 如何使用 Java 8 实现观察者模式
- 如何使用 Java8 实现观察者模式
- mysql 返回多个函数计算结果
- 写个观察者模式
- 将Thread对象作为Runnable对象使用的结果
- 2.5Groovy使用多赋值(方法的结果返回给多个变量)
- 安卓开发观察者模式应用-一个service通知多个activity更新ui的实现
- Java 观察者模式(类似于用接口实现回调)
- java 中的观察者模式实现之接口回调
- Java利用listener实现回调,即观察者模式
- css之鼠标样式
- iOS 解决cell滑动删除和scrollView左右滑动之间的冲突
- How To Validate A DataPump Export (EXPDP) Dump File ? (文档 ID 2113967.1) 转到底部 -------------------
- 【剑指offer】题27:二叉搜索树与双向链表
- Flask:用户认证
- 使用观察者模式实现线程将计算结果回调给多个对象
- 使用 aui 自带的图片轮播图,AJAX异步调用数据给它无法轮播问题
- StatisticsVariable
- Spring Boot动态监听jsp文件
- 用MDK建立STM32工程模板
- ARM 平台上的Linux系统启动流程
- 【codejam2008_Round1A_C】Numbers
- 常用命令
- PHP中关键字final和static