在GuardedSuspensionPattern保护暂停模式中,我们知道两个
线程操作操作临界资源,其中一个线程生产临界资源,另一个消费临界资源,后者需要临界资源的数量必须大于0,如果不大于0线程就会进入临界资源实例的等待区(wait),直到生产线程生产了一个临界资源,之后通知所有在临界资源实例的等待区的所有等待线程,等待线程得到通知后再继续去消费临界资源。
今天要介绍的是balk模式,退缩不前模式,意思就是当一个线程要去操作临界资源,在操作的时候需要判断一下是否满足操作的条件,如果满足就操作临界资源,不满足就直接return,而不是保护暂停模式中的“继续等待,直到条件满足”。
需求:当编辑一个文本文件时:要提供认为手动保存功能,和自动保存功能,自动保存的时候如果文本根本没有变化,则直接return 。我们通过两个线程来实现,一个线程负责编辑和认为保存,一个线程是自动保存功能。
涉及的类有:
1,Data类:表示临界资源
2,SaverThread :模拟自动保存的线程类
3,ChangerThread :模拟人为修改和人为保存的类
4,Main:测试类
代码如下:
class="java">package balking;
import java.io.FileWriter;
import java.io.IOError;
import java.io.IOException;
import java.io.Writer;
/*
* 表示现在数据(临界资源)的类
*/
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;//修改后的内容还没保存的话,值为true
}
public synchronized void change(String newContent){//在多线程中操作临界资源的方法都必须用synchronized修饰
content = newContent;
changed = true;//修改后的内容还没保存的话,值为true
}
public synchronized void save()throws IOException{//在多线程中操作临界资源的方法都必须用synchronized修饰
if(!changed){//如果已经保存则直接return。
return;
}
doSave(); //否则保存
changed = false;//保存后设置”是否需要保存的标志为"false
}
private void doSave()throws IOException{//注意该类并不需要用synchronized修改,因为该类是私有的,并且调用该方法的save()已经被synchronized修饰过
System.out.println(Thread.currentThread().getName() + "calls doSave,content = " + content);
Writer writer = new FileWriter(filename);//每次保存文件都会备份之间的文件,并且生成新的文件。
writer.write(content);
writer.close();
}
}
package balking;
import java.io.IOException;
/*
* 该线程类的实例主要用来模拟自动保存文件(每个一秒钟)
* 注意纵然该类用了一个死循环来一直调用data.save()进行文件保存,但并不是每个
* 调用save都执行了writer写操作,而是每次调用save时会首先判断该文件
* 是否已经保存了,如果已经保存了就直接返回了,然后再停一秒继续保存。
*/
public class SaverThread extends Thread {
private 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(IOException e){
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package balking;
import java.io.IOException;
import java.util.Random;
/*
* 该线程类的实例主要用来模拟人为修改,认为保存功能(修改后隔一分钟再保存)
*/
public class ChangerThread extends Thread{
private Data data;
private 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();
}
}
}
package balking;
/*
* 测试类
*/
public class Main {
public static void main(String[] args) {
Data data = new Data("data.tex","(empty");//临界资源实例
new ChangerThread("ChangerThread", data).start();//该线程用来模拟一个人不停的修改,保存文件
new SaverThread("SaverThread", data).start();//该线程用来模拟后台每隔一分钟自动保存文件
}
}