項目問題一、全域變數引起的並發問題,全域變數並發

來源:互聯網
上載者:User

項目問題一、全域變數引起的並發問題,全域變數並發
springmvc+hibernate+jdbctemplate+mysql

原文連結:http://blog.csdn.net/rugaxm/article/details/8551905

先看下面小段代碼,一個controller,一個service。

controller.java代碼:
    ........
    @Autowired
     private XXXService xxxService;
    ........
    @RequestMapping("/doXXX.do")
    public void doXXX(){
        .....
        xxxService.saveXXX(String content,....);
        .....
    }
    XXXService.java代碼:
    private String content;
    ......
    private void init(){//清空請求參數
        content = null;
        ......
    }
    public boolean saveXXX(String content, ......){
        this.init(content, ...);
        this.content = content;
        //商務邏輯處理
    }

以上這段代碼在訪問量不構成並發時不會出現什麼問題。 但當一個請求還未完成,另一個請求已經開始執行的情況下就會出現問題(並發): 第二個請求執行執行init()方法會將第一個請求的content變數設定為null或它本身的值,這樣資料就被篡改了。

    編碼者這樣寫的目的是因為content等變數需要在多個方法中使用,而且變數很多,但又不想通過方法參數的方式來傳遞,故使用成員變數。

    先看看為什麼會出現這種情況。 由於系統採用springmvc架構,springmvc核心控制器DispatcherServlet 預設為每個controller產生單一執行個體來處理所有使用者請求,所以在這個單一執行個體的controller中,它的XXXService也是一個執行個體處理所有請求, 這樣XXXService的成員變數就被所有請求共用。這樣就會出現並發請求時變數內容被篡改的問題。

那麼出現這種問題如何解決呢? 
    第一種方式: 既然是全域變數惹的禍,那就將全域變數都編程局部變數,通過方法參數來傳遞。
    第二種方式: jdk提供了java.lang.ThreadLocal,它為多線程並發提供了新思路。 (當使用ThreadLocal維護變數時,ThreadLocal為每個使用該變數的線程提供獨立的變數副本,所以每一個線程都可以獨立地改變自己的副本,而不會影響其它線程所對應的副本)
         那麼在什麼地方使用ThreadLocal呢? 什麼變數是請求公用的就將該變數託付給ThreadLocal來管理其線程副本, 所以我們在xxxService中使用它。
        XXXService.java代碼:
        private ThreadLocal<String> contentTL = new ThreadLocal<String>();
        //private String content;使用contentTL代替content;
        ......
        public boolean saveXXX(String content, ......){
            this.contentTL.set(content);  

            //商務邏輯處理
            //在各方法中使用content時候用this.contentTL.get()代替
    }  

     此類並發篡改資料的問題,可以在開發工具中設定斷點調試的方式來類比並發。即第一次請求運行到斷點時,查看content內容,並且不讓程式繼續往下運行,同時再發起一個請求,查看content內容。 如內容是第一次請求的內容,並且讓第一個請求跑完後,第二個請求到斷線處的content正確時,可以確定不會出現並發問題。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.