赞
踩
多个线程监控某个共享变量,A线程监控到共享变量发生变化后即将触发某个动作,但是此时发现有另外一个线程B已经针对该变量的变化开始了行动,因此A便放弃了准备开始的动作,我们把这样的线程间交互成为Balking(犹豫)设计模式。
看了以上两个例子的说明,想必大家已经清楚了Balking设计模式要解决的问题了吧,简短的说就是某个线程因为发现其他线程正在进行相同的工作而放弃即将开始的任务。
在本章中,我们将通过模拟word文档自动保存与手动保存的功能讲解
Balking模式之文档编辑
Document:
package MutilThreadModel.BalkingModel; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import static java.lang.Thread.currentThread; /** * Created by JYM on 2019/1/14 * 在Document中有两个主要方法save和edit分别用于保存文档和编辑文档。 * */ //代表正在编辑的文档类 public class Document { //如果文档发生改变,changed会被设置为true private boolean changed = false; //一次需要保存的内容,可以将其理解为内容缓存 private List<String> content = new ArrayList<>(); private final FileWriter writer; //自动保存文档的线程 private static AutoSaveThread autoSaveThread; //构造函数需要传入文档保存的路径和文档名称 private Document(String documentPath,String documentName) throws IOException { this.writer = new FileWriter(new File(documentPath,documentName),true); } //静态方法,主要用于创建文档,顺便启动自动保存文档的线程 public static Document create(String documentPath,String documentName) throws IOException { Document document = new Document(documentPath,documentName); autoSaveThread = new AutoSaveThread(document); autoSaveThread.start(); return document; } //文档的编辑,其实就是往content队列中提交字符串 public void edit(String content) { synchronized (this) { this.content.add(content); //文档改变,changed会变为true this.changed = true; } } //文档关闭的时候首先中断自动保存线程,然后关闭writer释放资源 public void close() throws IOException { autoSaveThread.interrupt(); writer.close(); } //save方法用于为外部显式进行文档保存 public void save() throws IOException { synchronized (this) { //balking,如果文档已经被保存了,则直接返回 if (!changed) { return; } System.out.println(currentThread()+" execute the save action"); //将内容写入文档中 for (String cacheLine : content) { this.writer.write(cacheLine); this.writer.write("\r\n"); } this.writer.flush(); //将changed修改为false,表明此刻再没有新的内容编辑 this.changed = false; this.content.clear(); } } }
在上面的代码中:
AutoSaveThread
package MutilThreadModel.BalkingModel; import java.io.IOException; import java.util.concurrent.TimeUnit; /** * Created by JYM on 2019/1/14 * 下面这个类函数实现的是文档的自动保存. * AutoSaveThread比较简单,其主要的工作就是每个一秒的时间调用一次document的save方法。 * */ public class AutoSaveThread extends Thread { private final Document document; public AutoSaveThread(Document document) { super("DocumentAutoSaveThread"); this.document = document; } @Override public void run() { while (true) { try { //每隔一秒自动保存一次文档 document.save(); TimeUnit.SECONDS.sleep(1); }catch (IOException | InterruptedException e) { break; } } } }
DocumentEditThread:
package MutilThreadModel.BalkingModel; import java.io.IOException; import java.util.Scanner; /** * Created by JYM on 2019/1/14 * DocumentEditThread线程则类似于主动编辑文档的作者,在DocumentEditThreadzhong中除了对文档进行修改编辑之外,还是同时按下Ctrl+S * 组合键(调用save方法)主动保存。 * */ //该线程代表的是主动进行文件编辑的线程,为了增加交互性,我们使用了Scanner public class DocumentEditThread extends Thread { private final String documentPath; private final String documentName; private final Scanner scanner = new Scanner(System.in); public DocumentEditThread(String documentPath,String documentName) { super("DocumentEditThread"); this.documentPath = documentPath; this.documentName = documentName; } @Override public void run() { int times = 0; try { Document document = Document.create(documentPath,documentName); //创建编辑文档 while (true) { //获取用户的键盘输入 String text = scanner.next(); if ("quit".equals(text)) { document.close(); break; } //将内容编辑到document中 document.edit(text); if (times==5) { //用户在输入了5次之后进行文档保存 document.save(); times=0; } times++; } }catch (IOException e) { throw new RuntimeException(e); } } }
/**
package MutilThreadModel.BalkingModel; /** * Created by JYM on 2019/1/14 * * 测试程序: * */ public class BalkingTest { public static void main(String[] args) { new DocumentEditThread("G:\\","balking.txt").start(); } } /** * Balking模式在日常的开发中很常见,比如在系统资源的加载或者某些数据的初始化时, * 在整个系统中声明中期中资源可能只被加载一次,我们就可以采用balking模式加以解决, * 代码如下: * public synchronized Map<String, Resource> load() * { * //balking * if(load) * { * return resourceMap; * }else * { * //do the resource load task; * //.... * this.loaded = true; * return resoureMap; * } * } * */
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。