java多線程之Balking模式介紹

Balk有拒絕,阻礙的意思。如果現在不適合執行這個操作,或者沒必要執行這個操作,就停止處理,直接返回。這就是Balking模式。

Balking 模式可以和Guarded Suspension 模式對比,都存在守護條件。而在Balking模式中,如果守護條件不成立就立即中斷處理,而Guarded Suspension 模式則是一直等待至可以運行。

創建4個類

名字 說明
Data 表示可以修改並保存的數據的類
SaverThread 定期保存數據內容的類
ChangerThread 修改並保存數據內容的類
Main 測試類
 
import java.io.FileWriter;
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;
    }
 
    // 修改數據內容
    public synchronized void change(String newContent){
        content = newContent;
        changed = true;
    }
 
    // 若數據內容修改過。則保存到文件中
    public synchronized void save() throws IOException {
        if (!changed){
            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();
    }
}
import java.io.IOException;
 
public class SaverThread extends  Thread{
 
    private final Data data;
 
    public SaverThread(String fileName ,Data data) {
        super(fileName);
        this.data = data;
    }
 
    @Override
    public void run() {
        try {
            while (true) {
                data.save();   // 要求保存數據
                Thread.sleep(1000);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
    }
}
import java.util.Random;
 
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;
    }
 
    @Override
    public void run() {
        try {
            for (int i = 0; true; i++) {
                data.change("No." + i);   // 修改數據
                Thread.sleep(random.nextInt(1000));  // 執行其他操作 ,隻是隨機暫停一段時間
                data.save();   // 顯式的保存
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

這裡註意Data類的doSava方法每次都是重新創建文件,文件內容會全部消失,該示例不能直接用作應用程序的自動保存功能,如果想做,必須對文件進行備份。

 
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();
    }
}

運行結果:沒有出現重復的編號。

Balking 模式中的登場角色

GuardedObject (被保護的對象)

GuardedObject 角色是一個擁有被防護的方法(guardedMethod)的類。當線程執行guardedMethod方法時,若守護條件成立,則執行實際的處理。反之,直接返回。守護條件的成立與否會隨著GuardedObject 角色的狀態變化而改變。

除瞭guardedMethod方法外,GuardedObject應該有改變狀態的方法(StateChangingMethod)。在上面示例中,由Data扮演此角色,sava方法則是guardedMethod,change方法則是StateChangingMethod。守護條件對應的是change屬性為true;

使用場景:

1 並不需要執行時

比如寫文件時,如果文件內容沒有變化,則無需再寫,提高程序性能。

2  不需要等待守護條件成立時

Balking模式的特點就是不進行等待,一旦守護條件不成立時,可以立即返回並進入下一個操作。這能夠大大提高程序的相應性。

3 守護條件僅在第一次成立時

例如我們先看看下面的代碼

 
public class Something {
    private boolean initialized =false;
    public synchronized void init(){
        if (initialized){
            return;
        }
        doInit();
        initialized = true;
    }
    
    private void doInit(){
        // 處理邏輯
    }
}

initialized 表示初始化是否完成,而這裡一旦初始化完成,initialized 就為true,而且狀態就永遠不會發生變化瞭。所以守護條件不成立時,直接返回。像這種initialized 字段,狀態僅變化一次的變量,我們通常稱為閉鎖。一旦把門鎖上瞭,就再也打不開瞭。

balk結果的表示方式:當從guardedMethod方法中balk並返回時,有如下表示方式

忽略balk通過返回值來表示balk,如true,false可以通過 異常的方式來表示

總結

到此這篇關於java多線程之Balking模式介紹的文章就介紹到這瞭,更多相關java多線程Balking模式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: