線程安全不安全寫法測試
在工作中代碼走查時發現部分代碼存在線程安全的隱患,一直想測試以下,在模擬web的http請求中,線程不安全的類放在請求controller中屬性位置和方法體內的不同表現
不安全的類:SimpleDateFormat
測試工具: jmeter
不安全的寫法
@RestController
public class TestThreadSafeController {
//線程不安全的類放在類的屬性中,在併發請求中,會出現線程安全的問題
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
@RequestMapping("getDate")
public void getDate(HttpServletResponse request,HttpServletResponse response){
try {
Date date = sdf.parse("20200317");
System.out.println(date.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
}
}
不安全寫法測試
線程組設置1000請求測試
可看到大概有25%的異常率
安全寫法
@RestController
public class TestThreadSafeController {
@RequestMapping("getSafeDate")
public void getSafeDate(HttpServletResponse request,HttpServletResponse response){
//線程不安全的類,放在請求方法體中,併發請求不會出現線程不安全的問題
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
try {
Date date = sdf.parse("20200316");
System.out.println(date.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
}
}
安全寫法測試
知識點
JMM定義了Java 虛擬機(JVM)在計算機內存(RAM)中的工作方式。JVM是整個計算機虛擬模型,所以JMM是隸屬於JVM的。從抽象的角度來看,JMM定義了線程和主內存之間的抽象關係:線程之間的共享變量存儲在主內存(Main Memory)中,每個線程都有一個私有的本地內存(Local Memory),本地內存中存儲了該線程以讀/寫共享變量的副本。本地內存是JMM的一個抽象概念,並不真實存在。它涵蓋了緩存、寫緩衝區、寄存器以及其他的硬件和編譯器優化。