【详解】多线程之Balking设计模式
分析
介绍
定期将当前数据内容写入文件中
,比如文本工具的自动保存功能,定期的将数据保存到文件中。当写入的内容和上次的内容完全相同时,再向文件写入就多余了,所以就不再执行写入操作
。- 所以这个程序就是以 数据内容不同 作为守护条件,如果数据内容相同,就不执行写入操作,直接返回(balk)
作用
- 当多个线程执行同一个操作时,如果已经执行过了,就可以不用再执行,提高程序的效率
编码实现
- 一个线程负责写数据
- 一个线程负责保存数据
- 在保存数据的地方最重要需要判断:
这次的修改是否已经保存
- 如果已经保存了,就
直接返回
public class Data {
private final String filename;
private String content;
private boolean changed;
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 ChangerThread extends Thread{
private final Data data;
private final Random random = new Random();
public ChangerThread(String name,Data data) {
super(name);
this.data = data;
}
@Override
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 class SaverThread extends Thread{
private final Data data;
public SaverThread(String name,Data data) {
super(name);
this.data = data;
}
@Override
public void run() {
try {
while (true){
data.save();//要求保存数据
Thread.sleep(1000);//休眠约一秒
}
}catch (IOException e){
e.printStackTrace();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
Data data = new Data("data.txt","(empty)");
new ChangerThread("ChangeThread",data).start();
new SaverThread("SaverThread",data).start();
}
}
结果
Waiter calls do save,content=No.0
Waiter calls do save,content=No.1
Waiter calls do save,content=No.2
Waiter calls do save,content=No.3
Customer calls do save,content=No.4
Customer calls do save,content=No.5
Customer calls do save,content=No.6
Waiter calls do save,content=No.7
Customer calls do save,content=No.8
Waiter calls do save,content=No.9
Customer calls do save,content=No.10
Waiter calls do save,content=No.11
Customer calls do save,content=No.12
Customer calls do save,content=No.13
Waiter calls do save,content=No.14
Customer calls do save,content=No.15
Waiter calls do save,content=No.16
Waiter calls do save,content=No.17
Customer calls do save,content=No.18
Customer calls do save,content=No.19
- 可以发现,对于每一次修改,要么用户手动保存,要么系统自动保存,不会出现保存两次的情况