除了守卫暂停模式(while),守护条件的模式,一种是Balk模式。像判断对象是否初始化,可以用这种模式。判断条件是if
- Balk模式:模拟服务器自动保存文件,用户修改保存同一个文件,如果服务器判断文件没有被修改,就不执行保存。
定义被保护对象Data,changed被synchronized保护表示文件状态的改变,用if来判断守护条件,如果文件没有被修改 changed=false那么就直接退出,即balk的含义
package com.example.Balking;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
// guard object 保卫对象
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;
}
// state change method 守护方法
public synchronized void change(String newContent){
// content 和changed一对被保护对象 被synchronized保护
content=newContent;
changed=true;
}
// guard method
public synchronized void save() throws IOException {
// 守护条件 changed不满足,不进行等待,直接返回。
if(!changed){// 文件没有被更改 if
// balk 看到文件没有被更改 走开
return;
}
doSave();// 如果执行异常执行不到changed=false
changed=false;
}
private void doSave() throws IOException {
System.out.println(Thread.currentThread().getName()+"calls doSave content= "+content);
Writer writer=new FileWriter(filename);
writer.write(content);
writer.close();
}
}
用户修改保存数据
package com.example.Balking;
import java.io.IOException;
import java.util.Random;
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;i<10;i++){
data.change("No:"+i);
Thread.sleep(random.nextInt(1000));
data.save();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器隔一秒自动保存数据
package com.example.Balking;
import java.io.IOException;
public class ServerThread extends Thread {
private final Data data;
public ServerThread(String name,Data data){
super(name);
this.data=data;
}
public void run(){
try{
while (true){
data.save();
Thread.sleep(1000);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.Balking;
public class Main {
public static void main(String[] args) {
Data data=new Data("data.txt", "{empty}");
new ChangerThread("ChangerThread",data).start();
new ServerThread("ServerThread", data).start();
}
}
结果:不会保存重复
ServerThreadcalls doSave content= No:0
ChangerThreadcalls doSave content= No:1
ChangerThreadcalls doSave content= No:2
ServerThreadcalls doSave content= No:3
ServerThreadcalls doSave content= No:4
ServerThreadcalls doSave content= No:5
ChangerThreadcalls doSave content= No:6
ChangerThreadcalls doSave content= No:7
ServerThreadcalls doSave content= No:8
ServerThreadcalls doSave content= No:9