import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class Test {
    public static void main(String[] args){
        BalkingTest.test();
    }
}

/*
    22.2 Balking模式之文档编辑

    多个线程监控某个共享变量,A线程监控到共享变量发生变化后即立即触发某个动作,但是
    此时发现另外一个线程B已经针对该变量的变化开始了行动,因此A便放弃了准备开始的工作
    ,我们把这种线程间交互称作Balking(犹豫)设计模式

        ——简而言之,就是当你去获取临界区资源时,发现正有人在使用着,那么你没有阻塞
            而是放弃了去获取这部分的资源。你认定,别的线程已经开始了对这部分资源的
            修改操作,所以你无需操作。
 */
class Document{
    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;
    }

    public void edit(String content) {
        synchronized (this) {
            this.content.add(content);
            this.changed=true;
        }
    }

    public void close() throws IOException{
        autoSaveThread.interrupt();
        writer.close();
    }

    public void save() throws IOException{
        synchronized (this) {
            if (!changed) {
                return;
            }

            System.out.println(Thread.currentThread()+" execute the save action");

            for (String cacheLine : content) {
                this.writer.write(cacheLine);
                this.writer.write("\r\n");
            }
            this.writer.flush();
            this.changed=false;
            this.content.clear();
        }
    }
}

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 (InterruptedException|IOException e) {
                break;
            }
        }
    }
}

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.edit(text);
                if (times == 5) {
                    document.save();
                    times=0;
                }
                times++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class BalkingTest{
    public static void test(){
        new DocumentEditThread(".","temp.tmp").start();
    }
}

Balking设计模式的更多相关文章

  1. java多线程12设计模式

    1.Single Threaded Execution Pattern(单线程运行模式) 2.Immutable Pattern(一成不变的模式) 3.Guarded Suspension Patte ...

  2. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  3. java EE设计模式简介

    1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...

  4. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  5. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  6. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  7. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

  8. .NET设计模式访问者模式

    一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...

  9. Java开发中的23种设计模式详解

    [放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...

随机推荐

  1. ubuntu Linux 操作系统安装与配置

    Ubuntu是一个以桌面应用为主的Linux操作系统.Ubuntu每六个月发布一个新版本(一般是4和10月份,命名为YY.MM),每一个普通版本都将被支持 18个月,长期支持版(Long Term S ...

  2. Resources.resx 未将对象引用设置到对象的实例

    原文:解决使用DevExpress开发错误:未将对象引用设置到对象的实例 在使用DevExpress是总是会出现一些状况.这次同事在他的机器上调试完毕的代码发过来,却出现“未将对象引用设置到对象的实例 ...

  3. android Choose library dependency 搜索不到目标库

    问题:Choose library dependency 搜索不到目标库,百度了一下,发现尽是废话,无解,反正就是升级ide,我是 android studio是2.3.3(网上说升级到3.+就好了, ...

  4. UWP入门(四)--设置控件样式

    原文:UWP入门(四)--设置控件样式 官方定义:可以使用 XAML 框架通过多种方式自定义应用的外观. 通过样式可以设置控件属性,并重复使用这些设置,以便保持多个控件具有一致的外观. 可分享至不同e ...

  5. Android零基础入门第82节:Activity数据回传

    上一节学习了将简单的数据从MainActivity传递到SecondActivity,本节一起来学习数据如何从SecondActivity回传到MainActivity. 一.简介 前面己经提到,Ac ...

  6. CS224n笔记一:开端

    何为自然语言处理 自然语言处理的目标是让计算机处理或者"理解"自然语言,以完成有意义的任务,如QA等. 自然语言处理涉及的层次 输入有两个来源:语音和文本,所以第一级是语音识别,O ...

  7. Linux可以把vmdk当做磁盘加载进去

    VMware虚拟机由于停电,无法启动MAC系统 下午的时候,正在开发ios app,结果停电了.当时还不知道,伴随而来的灾难竟然折腾了好几天,真是心力交瘁. 我是在VMware虚拟机下装的Mac os ...

  8. Qt4学习笔记 (7) 本篇说一下Qt对于脚本的支持, 即QtScript模块.

    本篇说一下Qt对于脚本的支持, 即QtScript模块. Qt支持的脚本基于ECMAScript脚本语言, 这个东西又是javascript, jscript的基础. 所以, 一般只要学过javasc ...

  9. postgres数据库小记

    因为工作中需要查询其他部门数据库,刚好是postgres数据库,用python链接的话,可以用psycopg2库,具体用法其实和MysqlDB是一样的,就是安装的时候遇到点问题. 安装的时候,提示: ...

  10. .NET程序员如何快入门Spring Boot

    本篇文章将教你作为一个.NET程序员如何快入门Spring Boot.你不需要用Eclipse,也不需要用IDEA.已经习惯了VS,其他的IDE-- 但不得不说VS Code很厉害,一用就喜欢.微软给 ...