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();
}
}
}
}
运行结果:
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.16
GuardedObject(被警戒对象的)参与者:
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则是对线程调用的。