线程跳动
總覽
線程jiggler是一個簡單的測試框架,用于執行代碼以查找線程問題。 它通過在運行時修改字節碼類的類來工作,以在指令之間插入Thread.yield()調用,從而“微動”線程。 這極大地增加了發現線程問題的可能性,并且無需更改生產代碼即可做到這一點。
背景
我最近正在研究如何測試多線程代碼中的線程問題,并從IBM找到了一個名為ConTest的工具,但找不到我可以使用的任何代碼。 很自然地,我以為我會自己加油。
考慮一下這個規范的簡單但線程不安全的類:
private int count = 0 ;public void count() {count++;}count方法的字節碼為:
DUP GETFIELD asm/Foo.counter : I ICONST_1 IADD PUTFIELD asm/Foo.counter : I這提供了幾個可以進行上下文切換的位置,這意味著可以增加計數,但未按預期存儲。 讓我們考慮一個快速的單元測試:
Counter counter = new BadCounter();int n = 1000;@Testpublic void singleThreadedTest() throws Exception {for (int i = 0; i < n; i++) {counter.count();}assertEquals(n, counter.getCount());}...該測試在單個線程中運行并通過。 讓我們嘗試在兩個線程上運行它,看看它是否失敗。
public void threadedTest() throws Exception {final CompletionService<Void> service = new ExecutorCompletionService<Void>(Executors.newFixedThreadPool(2));for (int i = 0; i < n; i++) {service.submit(new Callable<Void>() {@Overridepublic Void call() {counter.count();return null;}});}for (int i = 0; i < n; ++i) {service.take().get();}assertEquals(n, counter.getCount());}這也過去了。 在我的計算機上,我可以將n增加到100,000,直到它開始持續失敗。
Expected :1000000 Actual :999661只有0.04%的測試有問題。 我們學到了什么? 我們已經學會了一種運行多線程測試的簡單方法,但是我們已經知道,因為我們無法控制線程何時執行工作,所以這有點試驗和錯誤。
線程跳動
因此,行使代碼來發現線程缺陷的一個問題是您無法控制線程何時屈服。 但是,我們可以重寫字節碼,以便在指令之間的字節碼中插入Thread.yield()。 在上面的示例中,我們可以通過更改字節碼來獲取產生更多問題的代碼:
DUP GETFIELD asm/Foo.counter : I INVOKESTATIC java/lang/Thread.yield ()V ICONST_1 IADD PUTFIELD asm/Foo.counter : I使用ASM,我們可以創建一個重寫器來插入這些調用。 JigglingClassLoader即時重寫類,添加這些調用。 由此,我們可以創建一個JUnit運行器以使用新的類加載器進行測試來運行。
@Jiggle("threadjiggler.test.*") public class BadCounterTest {... }現在運行測試:
Expected :1000000 Actual :836403我們看到線程問題的測試數量躍升到16%。 我們無需重新編譯代碼,也不會影響在同一JVM中運行的其他單元測試。
讀者練習
SimpleDateFormat是Java中眾所周知的非線程安全類。 編寫一個使類動搖的測試。 為什么它不是線程安全的? 您將如何重寫它以確保線程安全? 您如何在不使用ThreadLocal,鎖或同步的情況下這樣做?
源代碼
可以在Github上找到此代碼。
進一步閱讀
我寫了一篇關于測試線程代碼是否正確的文章 。 您可能還希望更一般地閱讀:
- 并發的錯誤模式及其測試方法– Eitan Farchi,Yarden Nir,Shmuel Ur IBM Haifa Research Labs
- 介紹如何測試和調試并發軟件的困難的演講– Shmuel Ur
- Java理論與實踐:表征線程安全
翻譯自: https://www.javacodegeeks.com/2013/09/thread-jiggling.html
總結
- 上一篇: photoshop电脑版官方下载(pho
- 下一篇: 亚马逊DynamoDB