MQ監聽器下多線程安全問題

背景

今天在寫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

想要更多幹貨、技術猛料的孩子,快點拿起手機掃碼關注我,我在這裏等你哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章