Java自定義Once方法保障單次執行

最近在繼續學習Go語言的過程中,發現了一個比較神奇的的對象sync.Once,顧名思義,就是執行一次。官方定義的如下:Once是一個只執行一個動作的對象,看包名sync知道這是在併發使用場景。

基礎使用方法如下:

// TestOnceSimple once對象簡單測試
//  @Description: 
//  @param t
//
func TestOnceSimple(t *testing.T) {
	var once sync.Once
	for i := 0; i < 10; i++ {
		go once.Do(func() {
			log.Println("執行一次")
		})
	}
	time.Sleep(time.Second)
}

for循環裏面分別異步執行了10次,但是最終控制檯展示如下:

=== RUN   TestOnceSimple
2022/06/19 16:39:08 執行一次
--- PASS: TestOnceSimple (1.00s)
PASS

目前使用到場景中就是在各種配置進行初始化的時候,以防止多個異步同時來執行初始化任務導致異常。比如說,我再使用Redis連接池的時候,首先需要初始化連接池,通常需要一個方法來完成這個過程,大部分時候需要顯式調用,除非這個池對於我們項目來講是基礎的功能,程序啓動的時候就需要初始化。

這個在我寫Java的過程中,用到的HTTP的連接池和MySQL的連接池,而後者就屬於需要用的時候的再初始化的場景。還有一種方式,我們可以使用Java單例模式中的懶漢式的解決這個問題。但是我們如果在測試過程中使用不同的對象池的時候,這種方式又顯得比較死板不夠靈活。

所以在平時處理這種情況的時候,通常我會使用synchronized或者java.util.concurrent.locks.ReentrantLockconcurrent包裏面的工具類完成這個需求。具體代碼可參考Java單例的懶漢式的實現以及我之前的文章。

之前我對照Go語言的go異步關鍵字寫了Java自定義異步功能實踐,寫了一個Java版本的fun異步關鍵字。這次我自然計劃要抄一下sync.Once設計。

下面是我的經過自己嘗試寫了一個簡版的:

    static Vector<Integer> ones = new Vector<>();

    static ReentrantLock lock = new ReentrantLock();

    /**
     * 線程安全單次執行,仿照Go語言的once方法
     *
     * @param v
     */
    public static void once(Closure v) {
        try {
            lock.lock();
            int code = v.hashCode();
            if (!ones.contains(code)) {
                ones.add(code);
                v.call();
            }
        } catch (Exception e) {
            logger.warn("once執行方法失敗", e);
        } finally {
            lock.unlock();
        }
    }

下面是測試代碼:

package com.okcoin.hickwall.presses

import com.okcoin.hickwall.presses.funtester.httpclient.FunHttp 

class OnceTest extends FunHttp {

    public static void main(String[] args) {
        def test = {
            output("FunTester")
        }
        10.times {

            fun {
                once(test)
            }
        }

    }

}

控制檯輸出:

16:56:22 main 守護線程:Deamon開啓!
16:56:22 F-1  FunTester
16:56:23 Deamon 異步線程池等待執行1次耗時:6 ms
16:56:23 Deamon 異步線程池關閉!

從上面內容我們看到,雖然異步執行了10次,但是隻有一次真正執行了,實現了預期的需求。

Fun·BUG挖掘機·性能征服者·頭頂鍋蓋·Tester

閱讀原文,跳轉我的倉庫地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章