Balking 模式主要的目的就是當條件不成立時就不會進行處理的動作,這個適合的使用情境是在系統初始化時會被使用到,例如在系統第一次啟動的時侯會建立一些設定檔,等到之後的執行就不會去建立設定檔,因此適合使用 Balking 模式去做。或是當檔案的處理定期的存檔,如果發現有被修改才會去進行存檔的動作,這樣就可以避免檔案沒有修改也去存檔浪費 IO 的執行,這也是 Balking 模式常見的使用情境之一。
以下寫一個 sample code,來實作 Balking 模式,主要是可以在程式開始時印出一個 init 字串,當狀態改變時,就不會印出 init 字串而是印 running 字串,Sample Code 如下:
public class PrintString {
private boolean initFlag = false;
public synchronized void running(String message) {
if (!initFlag) {
System.out.println("init " + message);
initFlag = true;
}
System.out.println("running " + message);
}
}
以上的程式主要會用一個 flag 去判斷目前是有沒有初始化,如果還沒初始化就會先印出 init 的字串,之後就會把 flag 設定成 true,之後的執行緒都不會執行到印出 init 的字串,以下是執行緒的程式:
public class RunningExampleThread implements Runnable {
private PrintString printString;
public RunningExampleThread(PrintString printString) {
this.printString = printString;
}
@Override
public void run() {
String currentThread = Thread.currentThread().getName();
this.printString.running(currentThread);
}
}
在執行緒的程式主要會在 run 方法裡面,傳入目前執行的執行緒名稱給 printString 變數去印出目前是哪一個執行緒在執行,以下是主程式的寫法:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String args[]) {
PrintString p = new PrintString();
ScheduledExecutorService sec = Executors.newScheduledThreadPool(2);
sec.scheduleAtFixedRate(new RunningExampleThread(p), 2, 2, TimeUnit.SECONDS);
sec.scheduleAtFixedRate(new RunningExampleThread(p), 2, 2, TimeUnit.SECONDS);
}
}
在主程式裡面會使用 schedule 定時的每隔 2 秒執行印出字串,在第一個執行緒執行的時侯才會印出 init 字串,之後的執行只會印出 running 的字串,程式的執行結果如下:
init pool-1-thread-1
running pool-1-thread-1
running pool-1-thread-2
running pool-1-thread-1
running pool-1-thread-1
running pool-1-thread-2
running pool-1-thread-1
running pool-1-thread-1
running pool-1-thread-2
running pool-1-thread-1
running pool-1-thread-1