public class Main {
public static void main(String[] args) {
Data data=new Data("data.txt","(empty)");
new ChangerThread("ChangerThread", data).start();
new SaverThread("SaverThread", data).start();
}
}public class Data {
private 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) {
System.out.println(Thread.currentThread().getName()+" balks");
return;
}
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();
}
}public class ChangerThread extends Thread{
private Data data;
private Random random=new Random();
public ChangerThread(String name,Data data) {
super(name);
this.data=data;
}
@Override
public void run() {
for (int i = 0; true; i++) {
data.change("No."+i);
try {
Thread.sleep(random.nextInt(1000));//模拟去做其他的事情
data.save();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}public class SaverThread extends Thread{
private Data data;
public SaverThread(String name,Data data) {
super(name);
this.data=data;
}
@Override
public void run() {
while(true){
try {
data.save();
Thread.sleep(1000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
interrupt方法执行时:
运行结果:
SaverThread calls doSave,content =No.0 ChangerThread balks ChangerThread calls doSave,content =No.1 SaverThread calls doSave,content =No.2 ChangerThread balks ChangerThread calls doSave,content =No.3 ChangerThread calls doSave,content =No.4 SaverThread calls doSave,content =No.5 ChangerThread balks SaverThread calls doSave,content =No.6 ChangerThread balks ChangerThread calls doSave,content =No.7 SaverThread calls doSave,content =No.8 ChangerThread balks ChangerThread calls doSave,content =No.9 SaverThread calls doSave,content =No.10 ChangerThread balks ChangerThread calls doSave,content =No.11 SaverThread calls doSave,content =No.12 ChangerThread balks ChangerThread calls doSave,content =No.13 SaverThread calls doSave,content =No.14 ChangerThread balks ChangerThread calls doSave,content =No.15 SaverThread calls doSave,content =No.16GuardedObject(被警戒对象的)参与者:GuardedObject参与者是一个拥有被警戒的方法(guardedMethod)的类只要满足警戒条件,就会执行实例的方法。可能还有用来更改实例状态的方法(stateChangingMethod)。Data类就是GuardedObject参与者,save方法与change方法则分别是guardedMethod和stateChangingMethod。在Data中synchronized保护的是:content和changed字段。
Balking Pattern与Guarded Suspension Pattern的中间:
分别对应的模型
if(){ return; }while(){ wait(); }在“balk退出”与“等待到警戒条件为止”两种极端的处理方式之间,还有一种这种的做法——“在条件成立为止之前,等待一段时间”。等待一定的时间,看看警戒条件是不是会成立,如果还是不成立的话,就balk退出。这种方式称为guarded timed,或是简单的称为timeout。obj.wait(1000);interrupt方法执行时:
对这条线程执行interrupt方法时,被interrupt时,等待区里的线程会(与被调用notify、notifyAll一样),重新获取obj的锁定,并跑出InterruptException。notify、notifyAll是对实例调用的,而interrupt则是对线程调用的。