使用Java ThreadLocals的意外递归保护
生活随笔
收集整理的這篇文章主要介紹了
使用Java ThreadLocals的意外递归保护
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對于那些使用第三方工具來嘗試擴展它們而又不完全了解它們的人來說,這是一個小技巧。 假定以下情況:
- 您想擴展一個公開分層數據模型的庫(假設您要擴展Apache Jackrabbit )
- 該庫在訪問內容存儲庫的任何節點之前會內部檢查訪問權限
- 您想實現自己的訪問控制算法
- 您的訪問控制算法將訪問內容存儲庫的其他節點
- …反過來又會觸發訪問控制
- …進而將再次訪問內容存儲庫的其他節點
…無限遞歸,如果不遞歸廣度優先,則可能會導致StackOverflowError 。
現在,您有兩個選擇:
當然,您確實應該選擇選項1。但是,誰有時間了解所有內容?
這是實現該技巧的方法。
/*** This thread local indicates whether you've* already started recursing with level 1*/ static final ThreadLocal<Boolean> RECURSION_CONTROL= new ThreadLocal<Boolean>();/*** This method executes a delegate in a "protected"* mode, preventing recursion. If a inadvertent* recursion occurred, return a default instead*/ public static <T> T protect(T resultOnRecursion,Protectable<T> delegate) throws Exception {// Not recursing yet, allow a single level of// recursion and execute the delegate onceif (RECURSION_CONTROL.get() == null) {try {RECURSION_CONTROL.set(true);return delegate.call();}finally {RECURSION_CONTROL.remove();}}// Abort recursion and return earlyelse {return resultOnRecursion;} }/*** An API to wrap your code with*/ public interface Protectable<T> {T call() throws Exception; }在此用法示例中可以很容易地看出這一點:
public static void main(String[] args) throws Exception {protect(null, new Protectable<Void>() {@Overridepublic Void call() throws Exception {// Recurse infinitelySystem.out.println("Recursing?");main(null);System.out.println("No!");return null;}}); }對main()方法的遞歸調用將被保護方法終止,并提早返回,而不是執行call() 。 也可以通過使用ThreadLocals Map進一步詳細說明此思想,從而允許指定各種鍵或上下文以防止遞歸。 然后,您還可以將Integer放入ThreadLocal ,在遞歸時將其遞增,最多允許N個遞歸級別。
static final ThreadLocal<Integer> RECURSION_CONTROL= new ThreadLocal<Integer>();public static <T> T protect(T resultOnRecursion,Protectable<T> delegate) throws Exception {Integer level = RECURSION_CONTROL.get();level = (level == null) ? 0 : level;if (level < 5) {try {RECURSION_CONTROL.set(level + 1);return delegate.call();}finally {if (level > 0)RECURSION_CONTROL.set(level - 1);elseRECURSION_CONTROL.remove();}}else {return resultOnRecursion;} } 但是再說一次。 也許您應該再花幾分鐘時間,了解主機庫的內部機制是如何工作的,并從一開始就將事情做好……與往常一樣,在使用技巧和黑客手段時!
翻譯自: https://www.javacodegeeks.com/2013/04/inadvertent-recursion-protection-with-java-threadlocals.html
總結
以上是生活随笔為你收集整理的使用Java ThreadLocals的意外递归保护的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信理财通每日收益怎么算的?
- 下一篇: 深圳中兴通讯厂在哪里