Balking
Balking模式介绍
如果现在不适合执行这个操作,或者没必要执行这个操作,就停止处理,直接返回;
Balking模式的使用场景
- 线程并不需要执行;由于某种操作已经被其他同类线程执行,而该线程没有必要重复执行操作时,可以使用Balking模式;
- 不需要等待守护条件成立;守护条件成立,表明该操作可以执行,线程进行处理即可;当守护条件不成立,表明该操作没有执行的必要,该线程不需要等待其成立(从而提高了效率);
- 仅在守护条件第一次成立时执行某种操作;比如多线程初始化同一个资源,但资源只需要初始化一次,此时可以使用Balking模式;实际上,“状态仅改变一次的变量”,我们通常称为闭锁,一旦该门闩插上,就再也打不开了;
Balking示例代码分析
下面是一个模拟“自动保存”功能的多线程代码示例,虽然并不能直接应用于生成代码中(因为业务逻辑并不全面,比如保存文档时的没有进行备份),但是可以用来很好地了解Balking模式;
//多线程访问安全的数据类
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;
changed=true;
}
public synchronized void change(String newContent){
content=newContent;
changed=true;
}
public synchronized void save() throws IOException {
if(!changed){
return;
}//Balking
doSave();
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();
}
}
//保存Data的线程
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);
}
}catch(InterruptedException | IOException d){
d.printStackTrace();
}
}
}
//改变Data的线程
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 |InterruptedException e){
e.printStackTrace();
}
}
}
//启动类
public class Tester {
public static void main(String[] args){
Data data=new Data("slx.txt","不抛弃,不放弃");
new ChangerThread("changerThread",data).start();
new SaverThread("saverThread",data).start();
}
}
SaverThread的存在提高了ChangerThread的执行效率,因为ChangerThread必然要调用data的save方法以确保下一次改动之前数据被存储,但是真正的doSave操作却不一定是因为ChangerThread调用而被执行,因为有SaverThread啊~ 这样ChangerThread就能更快滴执行下一次change方法啦;
对Balking模式的理解
Balking模式和Guarded Suspension模式一样,存在守护条件,如果守护条件不满足,则中断处理;这与Guarded Suspension模式不同,Guarded Suspension模式在守护条件不满足的时候会一直等待至可以运行;
Balking模式是一种多个线程执行同一操作A时可以考虑的模式;在某一个线程B被阻塞或者执行其他操作时,其他线程同样可以完成操作A,而当线程B恢复执行或者要执行操作A时,因A已被执行,而无需线程B再执行,从而提高了B的执行效率;