Java 高并发编程详解 12.0 Balking模式

Balking模式

线程任务发现其他线程正在执行相同的工作而放弃即将开始的任务。下面实例模拟word文档自动保持和手动保持功能来了解。当手动保持和自动保持冲突时,自动保持放弃执行其任务。

文档类


/**
* 文档类
*/
public class Document {
   // 是否被修改标识
   private boolean changed = false;
   // 要保存的内容
   private List<String> content = new ArrayList<>();
   // 输出流
   private final FileWriter writer;
   // 自动保持文件的线程
   private static AutoSaveThread autoSaveThread;
   // 构造传入文件的路径和名称
   private Document(String path,String name) throws IOException {
       this.writer = new FileWriter(new File(path,name),true);
   }
   // 静态方法 用于创建文档 并开启自动保持文档的线程
   public static Document create(String path,String name) throws IOException{
       Document document = new Document(path, name);
       autoSaveThread = new AutoSaveThread(document);
       autoSaveThread.start();
       return document;
   }
   // 文档编写, 将编写信息设置到content中
   public void edit(String content){
       synchronized (this){
           this.content.add(content);
           this.changed = true;
       }
   }
   // 文档关闭 先中断自动保持线程 再关闭writer释放资源
   public void close() throws IOException{
       autoSaveThread.interrupt();
       writer.close();
   }
   // 保存
   public void save() throws IOException{
       synchronized (this){
           // balking 如果文档已经保存 则直接返回
           if (!changed){
               return;
           }
           System.out.println("线程为"+Thread.currentThread().getName()+"------------开始调用保存-----------");
           for (String caheLine:content){
               this.writer.write(caheLine);
               this.writer.write("\r\n");
           }
           this.writer.flush();
           // 修改标识 清空修改内容
           this.changed = false;
           this.content.clear();
       }
   }
}

自动保存文档线程类


/**
 * 自动保存线程
 */
public class AutoSaveThread extends Thread {
    private final Document document;

    public AutoSaveThread(Document document) {
        // 设置线程别名
        super("自动保存线程");
        this.document = document;
    }

    @Override
    public void run() {
        while (true){
            try {
                // 每隔一秒保存一次文档
                document.save();
                TimeUnit.SECONDS.sleep(1);
            }catch (IOException | InterruptedException e){
                break;
            }
        }
    }
}

文档使用线程类


/**
 * 该线程 类似于主动编辑文档的作者 使用文档
 */
public class DocumentEditThread extends Thread{
    // 文件地址
    private final String path;
    // 文件名称
    private final String name;
    // 命令行输入
    private final Scanner scanner = new Scanner(System.in);

    public DocumentEditThread(String path, String name) {
        super("文档编写线程");
        this.path = path;
        this.name = name;
    }

    @Override
    public void run() {
        int time = 0;
        try {
            Document document = Document.create(path, name);
            while (true){
                // 获取用户键盘输入
                String next = scanner.next();
                // 退出
                if("quit".equals(next)){
                    document.close();
                    break;
                }
                // 编辑
                document.edit(next);
                // 模拟手动保存
                if (time == 5){
                    document.save();
                    time = 0;
                }
                time++;
            }
        }catch (IOException e){
            throw new RuntimeException(e);
        }
    }
}

测试类

public class BalkingTest {
    public static void main(String[] args) {
        new DocumentEditThread("C:\\Java","balking.txt").start();
    }
}

当第六次输入信息保存时会走手动保存

1111
线程为自动保存线程------------开始调用保存-----------
2222
线程为自动保存线程------------开始调用保存-----------
3333
线程为自动保存线程------------开始调用保存-----------
4444
线程为自动保存线程------------开始调用保存-----------
5555
线程为自动保存线程------------开始调用保存-----------
6666
线程为文档编写线程------------开始调用保存-----------
quit

使用balking模式实现资源只被加载一次

    private boolean loaded = false;
    private final Map<String,List<String>> applicationContext = new HashMap<>();
    public synchronized Map<String, List<String>> load(){
        //balking 标识为true时取已经加载好的数据
        if(loaded){
            return applicationContext;
        }else {
            // 初始化一次
            applicationContext = new HashMap<>();
            this.loaded = true;
            return applicationContext;
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值