第四章 Balking模式

本文深入解析Balking设计模式,探讨其在多线程环境中如何通过检查条件避免不必要的操作,提高程序效率。通过示例程序展示Balker模式在自动保存功能中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【Backing模式】

如果现在不适合执行这个操作,或者没必要执行这个操作,就停止处理,直接返回。Balking模式与Guarded Suspension模式一样,也存在守护条件。在Balking模式中,如果守护条件不成立,则立即中断处理。这与Guarded Suspension模式有所不同,因为 Guarded Suspension模式是一直等待至可以运行。

【示例程序】

文本工具的自动保存功能,为了防止电脑突然死机而定期地将数据保存到文件的功能。

当写入的内容与上次写入的内容完全相同时,再向文件写入就显得多余了,所以就不再执行写入操作。也就是说,改程序以“数据内容存在不同”作为守护条件,如果数据内容相同,则不执行写入操作,直接返回balk。

名字

说明

Data

表示可以修改并保存的数据的类

SaverThread

定期保存数据内容的类

ChangerThread

修改并保存数据内容的类

Main

测试程序行为的类

public class Data {

     private final String filename;    //保存的文件名称

     private String content;           //数据内容

     private boolean changed;          //修改后的内容若未保存,则为true

     

     public Data(String filename, String content) {

          this.filename=filename;

          this.content=content;

          this.changed=true;

     }

     

     //修改数据内容

     public synchronized void change(String newContent) {

          content=newContent;

          changed=true;

     }

     

     //若数据内容修改过,则保存到文件中

     public synchronized void save() throws IOException {

          if(!changed) return;

          doSave();

          changed=false;

     }

     

     //将数据内容实际保存到文件中

     public void doSave() throws IOException {

          System.out.println(Thread.currentThread().getName()+" calls doSave, content = "+content);

          Writer writer = new FileWriter(filename);

          writer.write(content);

          writer.close();

     }

}

public class SaverThread extends Thread {

     private final Data data;

     public SaverThread(String name, Data data) {

          super(name);

          this.data=data;

     }

     public void run() {

          try{

              while(true){

                   data.save();//要求保存数据

                   Thread.sleep(1000);//休眠约1秒

              }

          } catch(IOException e) {

              e.printStackTrace();

          } catch(InterruptedException e) {

              e.printStackTrace();

          }

     }

}

public class ChangerThread extends Thread {

     private final Data data;

     private final Random random = new Random();

     public ChangerThread(String name, Data data) {

          super(name);

          this.data=data;

     }

     public void run() {

          try {

              for(int i=0;true;i++) {

                   data.change("No."+i);

                   Thread.sleep(random.nextInt(1000));

                   data.save();

              }

          }catch(IOException e) {

              e.printStackTrace();

          } catch(InterruptedException e) {

              e.printStackTrace();

          }

     }

}

public static void main(String[] args) {

     Data data = new Data("Data.txt", "(empty)");

     new ChangerThread("ChangerThread",data).start();

     new SaverThread("SaverThread",data).start();

}

【Balking模式登场的角色】

GuardObject被防护的对象

GuardObject角色是一个拥有被守护方法的类。当线程执行guardMethod方法时,若守护方法成立,则执行实际的处理。而当守护条件不成立时,则不执行实际的处理,直接返回。守护条件的成立与否,会随着GuardObject角色的状态变化而发生变化。

除了guardMethod之外,GuardObject角色还有可能有其他来改变状态的方法。

守护条件为changed字段为true.

 

【何时可用】

1.并不需要执行时

在示例程序中,content字段的内容并没有发生修改时,就将save方法balk了。

之所以balk,是因为content的内容已经写进文件中了,无需再耗费功夫去写了。

2.不需要等待守护条件成立时

Balking模式的特点就是“不进行等待”。若守护条件不成立时,想要立即返回并进入下一个操作。这能够提高程序的响应性。

3.守护条件仅在第一次成立时

 

【小结】

Balking模式——对象本身拥有状态,该对象只有在自身状态合适时才会执行处理,否则便不会执行处理。

使用if来检查守护条件

 

【练习题1】

阅读下面关于示例程序的内容,叙述正确请打√,错误请打×

1.save方法仅可由SaverThread调用

×答:save方法可由SaverThread和ChangerThread调用。

2.将所有的synchronized都删掉,并将changed字段声明为volatile之后,程序运行仍然是一样的。

×答:由于change方法㛑save方法都不再是Single Threaded Execution模式,运行也就不同。即使声明为volatile,线程的互斥处理也不会被执行。

3.doSave方法不是synchronized方法。

√答:doSave方法并不是synchronized方法。但是由于 doSave方法仅由synchronized方法调用,所以执行到doSave方法的线程一定持有this的锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值