word自动保存功能,如果文档被修改了,后台线程每隔一段时间会自动执行保存功能,但是如果用户在自动保存之前用Ctrl+S手动保存呢?自动保存还会执行吗?答案是不会,因为这个操作时不需要重复做的。
public class BalkingTest { public static void main(String[] args) { Data data = new Data("data.txt","(empty)"); new ChangerThread("ChangerThread", data).start(); new AutoSaverThread("AutoSaverThread", data).start(); } } 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() { 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(); } } } class AutoSaverThread extends Thread{ private Data data; public AutoSaverThread(String name, Data data){ super(name); this.data=data; } @Override public void run() { try{ while(true){ data.save(); Thread.sleep(3000); } }catch(IOException e){ e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } 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; } public synchronized void change(String newContent){ this.content = newContent; this.changed=true; } public synchronized void save() throws IOException{ if(!changed){ return; } doSave(); changed=false; } private void doSave() throws IOException { System.err.println(Thread.currentThread().getName()+" call doSave(), content = "+ content); Writer writer = new FileWriter(filename); writer.write(content); writer.close(); } }
这样就不会重复保存了,执行结果如下:
AutoSaverThread call doSave(), content = No.0 ChangerThread call doSave(), content = No.1 ChangerThread call doSave(), content = No.2 ChangerThread call doSave(), content = No.3 ChangerThread call doSave(), content = No.4 AutoSaverThread call doSave(), content = No.5 ChangerThread call doSave(), content = No.6 ChangerThread call doSave(), content = No.7 ChangerThread call doSave(), content = No.8 ChangerThread call doSave(), content = No.9 ChangerThread call doSave(), content = No.10 AutoSaverThread call doSave(), content = No.11 ChangerThread call doSave(), content = No.12 ChangerThread call doSave(), content = No.13 ChangerThread call doSave(), content = No.14 ChangerThread call doSave(), content = No.15 AutoSaverThread call doSave(), content = No.16
还有一种情况,就是一个类的一个方法只想被执行一次,我们可以用Balking 模式处理。
class RunOnceTime{ private boolean initialized = false; public synchronized void init(){ if(initialized == true){ return; } doInit(); initialized = true; } private void doInit(){ } }