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. 【转】ORACLE AWR报告

    转自:http://blog.csdn.net/liqfyiyi/article/details/8236864 About Oracle AWR Oracle AWR is a powerful m ...

  2. Linux精要

    Linux入门精要 Linux历史 1970年: linux元年,起始开发者为 Kenneth Lane Thompson 和 Dernis Ritchie, 现在知道为啥很多计算机是用1970年1月 ...

  3. 解决npm install卡住不动的小尴尬

    npm install卡顿问题记录 遇到的问题 npm install -g @angular/cli 安装angular cli工具时,发现进度条一直卡住不动,相信很多朋友也遇到过.原因应该是国内的 ...

  4. SpringBoot整合日志框架LogBack

    日志可以记录我们应用程序的运行情况,我们可以通过日志信息去获取应用程序更多的信息.常用处理java日志的组件有:slf4j.log4j.logback.common-logging等.其中log4j是 ...

  5. React性能优化之PureComponent 和 memo使用分析

    前言 关于react性能优化,在react 16这个版本,官方推出fiber,在框架层面优化了react性能上面的问题.由于这个太过于庞大,我们今天围绕子自组件更新策略,从两个及其微小的方面来谈rea ...

  6. 01-pymysql模块的安装

    1.从github 下载pymysql 安装包,下载地址为:https://github.com/PyMySQL/PyMySQL 2.解压下载文件,不用打开python交互界面,cd到解压文件所在目录 ...

  7. 【Java源码】集合类-JDK1.8 哈希表-红黑树-HashMap总结

    JDK 1.8 HashMap是数组+链表+红黑树实现的,在阅读HashMap的源码之前先来回顾一下大学课本数据结构中的哈希表和红黑树. 什么是哈希表? 在存储结构中,关键值key通过一种关系f和唯一 ...

  8. Java NIO 学习笔记(一)----概述,Channel/Buffer

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  9. 【python3两小时根本不够】入门笔记04:线程+Lock安全同步

    有了简单爬虫,但是效率实在是太慢,于是决定启用线程进行爬取数据 但是对于临界资源的定义不好把握,思路如下: 1.定义队列(Queue的数据结构,List也可,安全性待考究) demo:https:// ...

  10. Java虚拟机详解(二)------运行时内存结构

    首先通过一张图了解 Java程序的执行流程: 我们编写好的Java源代码程序,通过Java编译器javac编译成Java虚拟机识别的class文件(字节码文件),然后由 JVM 中的类加载器加载编译生 ...