Holo314/Coeffect:使用Loom的ExtentLocals將部分Coeffect系統新增到Java
在 Java 中,通常有兩種策略來管理方法所需的引數:
- 將值作為引數傳遞
- 將值作為類的欄位
此外,為了確保執行緒安全,我們需要做更多的工作。對於第一種方法,問題不太明顯,但對於後者,則更難處理。
確保安全的一種方法是使用 Java 的ThreadLocal,它可以確保引數不能透過不同的執行緒:
public class Example { private static ThreadLocal<String> TL = new ThreadLocal<>(); public void foo() { System.out.println(Example.get()); } public static void main(String[] args) { var x = new Example(); CompletableFuture.runAsync(() -> { TL.set("^o^"); Thread.sleep(3000); // omitting exception handling x.foo(); }); CompletableFuture.runAsync(() -> { Thread.sleep(1000); // omitting exception handling TL.set("o7"); x.foo(); }); } } |
這將列印
o7 ^o^ |
Project Loom 已經新增了ExtentLocal,它基本上就是一個結構化的ThreadLocal.
ThreadLocal和ExtentLocal的最有問題的是:我們失去了型別安全。對於ThreadLocal,你可以得到意想不到的空值,而對於ExtentLocal,你會得到一個異常。
任何對ThreadLocal或ExtentLocal的使用都應該附加一個null檢查或繫結檢查。此外,如果這兩者中的一個不是私有的,就會產生耦合、安全問題和模糊的API。
另一方面,將依賴項作為引數傳送還有其他問題,但我要談的主要有兩個:
- 引數膨脹
- 強制顯式繫結
第一點很清楚,您可以獲取具有 5/6 或更多引數的方法,這會在呼叫站點中建立長簽名以及長簽名。
第二點更容易忽略,但這裡有一個例子:
public static void main(String[] args) { foo(666) } public static void foo(int x) { bar(x); } public static void bar(int x) { System.out.println(x); } |
請注意,foo接收一個引數只是為了將它傳遞給bar,它實際上並沒有對它做任何事情。
解決方案
這個庫提供的解決方案是建立一個(部分)Coeffect System。
這個想法是使用ExtentLocal一個編譯器外掛來增加安全性和明確性。
Implementation note:無法建立此係統,ThreadLocal因為無法控制ThreadLocalremove.
在深入瞭解細節之前,讓我們看看上面的例子是什麼樣子的:
public static void main(String[]args){ Coeffect.with(666) .run(() -> foo()); } @WithContext(Integer.class) public static void foo(){ bar(); } @WithContext(Integer.class) public static void bar(){ System.out.println(Coeffect.get(Integer.class)); } |
- 我們在bar中使用Coeffect.get(Integer.class)來獲取儲存在全域性Coeffect中的頂部整數。
- 我們用@WithContext(Integer.class)對bar進行了註解,以表示我們在方法中使用Integer。
- 我們在foo中呼叫了bar。
- 我們用@WithContext(Integer.class)註釋了foo,以表示我們正在使用一個需要Integer的方法。
- 我們呼叫Coeffect.with(666)將666放在Integer.class的棧頂。
- 我們在Coeffect.with(666)上呼叫run,在當前棧中執行一個Runnable。
- 在Coeffect.with(666).run子句中,我們正在執行foo
- 我們不需要在main方法中指定@WithContext(Integer.class),因為我們沒有使用任何非繫結的依賴關係
請注意,所有這些點都是在編譯時強制執行的,刪除任何一個,@WithContext編譯器都會對你大喊大叫。
Coeffect建立在ExtentLocal專案 Loom 附帶的基礎之上,以補充結構化併發,這意味著所有與執行緒一起工作並Coeffect一起使用的都應該使用結構化併發,任何非結構化併發的使用都可能導致誤報。
名字Coeffect來自Effectsystem。Java確實有一個(部分)Effect System,checked exceptions,一個 effect 和一個 coeffect 的區別是比較細的,我希望以後給Coeffect型別系統和 Checked Exceptions 一樣的力量
詳細點選標題
相關文章
- 怎麼將Defender圖示新增到win10系統工作列Win10
- win10系統下怎麼將應用程式新增到信任列表Win10
- Win10系統中怎麼將Store遊戲應用新增到SteamWin10遊戲
- 【教程】將Java條形碼新增到PDF文件的兩種方法Java
- [筆記]如何將已存在的JAVA新增到當前ECLIPSE JAVA工程中筆記JavaEclipse
- 華為榮耀新機榮耀V20部分配置曝光:將執行安卓9.0系統安卓
- Win10系統下怎麼將本機遊戲新增到Xbox中Win10遊戲
- 英國央行將測試DLT在新結算系統中的使用
- Win10系統下怎麼將加密檔案新增到搜尋索引中Win10加密索引
- Win10系統下怎麼將pin新增到使用者賬戶_win10新增PIN密碼的方法Win10密碼
- Premiere Elements使用教程:將音樂新增到影片片段REM
- JavaProjects - LoomJavaProjectOOM
- 將聚合新增到 Elasticsearch 查詢Elasticsearch
- 1.7.5. 將使用者新增到密碼檔案中密碼
- 將使用者新增到一個指定組 linux usermodLinux
- 新建使用者並將使用者新增到root使用者組內
- 掌握Java9模組化系統-基礎部分Java
- 掌握Java9模組化系統-進階部分Java
- windows10系統下怎麼將網址或資料夾新增到收藏夾中Windows
- 儲存系統市場將面臨新的挑戰
- Project Loom帶來Java併發模型革命? - infoworldProjectOOMJava模型
- MimoLive for mac使用教程,將媒體檔案新增到mimoLive?Mac
- FreeBSD使用deamon將frpc新增到開始啟動項FRPRPC
- 用VB寫的一個元件,實現新增系統使用者,並新增到指定組元件
- 微軟稱win10系統將禁止部分防毒防毒軟體和深度嵌入系統的遊戲執行微軟Win10防毒遊戲
- UAC:如何將軟體新增到信任區
- mac 下將 mamp mysql新增到全域性MacMySql
- 將Tomcat Admin新增到TomcatTomcat
- 如何將 SSH Key 新增到 GitLab 中?Gitlab
- 我的“Java實用系統開發指南”即將出版Java
- 如何透過PHP將“if”新增到給定字串的前面PHP字串
- C#將自己的程式新增到右鍵選單C#
- 使用Loom建立虛擬執行緒 - davidOOM執行緒
- win10如何將程式新增在開始選單 win10系統將應用程式新增到開始選單的步驟Win10
- 微軟稱將要把部分軟體與XP系統捆綁銷售 (轉)微軟
- 【小型系統】抽獎系統-使用Java Swing完成Java
- 基於java的外賣點餐系統部分模組設計(無介面版)Java
- 將ServiceLoader遷移到Java 9模組系統 - frankelJava