背景
今天在寫MQ隊列監聽器隊列的時候,突然有一個疑問,局部變量會不會受到多線程的影響,所以爲此做了一個實驗。
實驗
我在監聽器中定義了兩個變量,一個是類變量,一個是局部變量。然後設置監聽器的併發線程爲2個、一次抓取線程的消息個數爲10個,具體代碼如下所示:
public int countPublic = 0;
@Override
@RabbitHandler
@RabbitListener(queues = "amz_advertisement:big_info", containerFactory = "rabbitListenerContainerFactoryAmzAdvertisementBig")
public void process(Message msg, Channel channel) {
int countPrivate = 0;
try {
countPrivate++;
countPublic++;
logger.error("countPrivate:{},countPublic:{}", countPrivate, countPublic);
} catch (Exception e) {
logger.error("bigInfo錯誤,錯誤信息爲:{}", ExceptionUtil.formatException(e));
}
}
然後循環發送100個消息,推送到指定隊列中,具體代碼如下所示:
@RequestMapping("/sendMQ/{message}")
public Object sendMQ(@PathVariable("message") String message) throws InterruptedException {
for (int i=0;i<100;i++){
Thread.sleep(100);
amqpTemplateDelay.convertAndSend("amz_advertisement:big_info", "我是測試amz_advertisement:info的測試數據");
}
return "發送成功";
}
結果如下所示:
RabbitListenerEndpointContainer#0-1 [BigInfoAdvertistingListener.java: 43] - countPrivate:1,countPublic:1
RabbitListenerEndpointContainer#0-1 [BigInfoAdvertistingListener.java: 43] - countPrivate:1,countPublic:3
RabbitListenerEndpointContainer#0-2 [BigInfoAdvertistingListener.java: 43] - countPrivate:1,countPublic:3
RabbitListenerEndpointContainer#0-2 [BigInfoAdvertistingListener.java: 43] - countPrivate:1,countPublic:4
從結果中,我們可以很明顯的看到:局部變量一致都是1沒有遞增,但是類變量一直在遞增。
這是因爲Spring默認以單例模式創建對象,所以多線程模式下類變量就會存在線程安全問題。但是局部變量,在多線程模式下是線程安全的,各個線程之間的局部變量都是獨享的。
總結
有時候我們寫代碼不注意,就會把局部變量寫成類變量,這個時候如果是多線程模式,那將是災難性的。所以我們平時寫代碼一定要嚴謹,不要變量位置隨意放置。今天的初試多線程就到這邊,下一講博主將會深入的給大家介紹複雜多線程應用場景。
林老師帶你學編程:https://wolzq.com
想要更多幹貨、技術猛料的孩子,快點拿起手機掃碼關注我,我在這裏等你哦~