項目問題一、全局變數引起的併發問題

来源:http://www.cnblogs.com/huanhailanyu/archive/2017/11/09/7808527.html
-Advertisement-
Play Games

springmvc+hibernate+jdbctemplate+mysql 原文鏈接:http://blog.csdn.net/rugaxm/article/details/8551905 先看下麵小段代碼,一個controller,一個service。 controller.java代碼: .. ...


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正確時,可以確定不會出現併發問題。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 提取文本的情況在工作和學習中常會遇到,在前面的文章中,已經講述瞭如何提取PPT中文本框里的文本,在本篇文章中,將介紹如何使用C#代碼語言提取PPT文檔中SmartArt和批註中的文本。同樣的,程式裡面需要使用到Spire.PPT for .NET,在編寫代碼前,需先安裝,並添引用dll文件到項目程式 ...
  • 新開一個Web site。沒有使用jQuery,當Insus.NET使用一些驗證控制項時,如RequiredfieldValidator,程式出現下麵錯誤: WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for ...
  • Dapper使用技巧和基礎CRUD 一、使用模型的增刪改查。 2.建立資料庫 3.數據增刪改查 引用比較亂,做了一些測試,順便說說MongoDB.Driver也很好用,下次寫。 備註:傳入參數可以直接用模型,也可以用object new {Name="test",Code="Test"};這是我寫這 ...
  • 問題 由於在初學c#的時候 使用了 線程委托去執行函數,是為了不讓軟體窗體假死。所以使用下方代碼: Thread th = new Thread(Getform); //創建線程 th.Start(); 在使用前需要引入 : using System.Threading; 但是,在Getform 函 ...
  • .NET中的線程池是受CLR管理的,TheadTool類有一個QueueUserWorkItem靜態方法,這個靜態方法接受一個委托,代表用戶自定義的一個非同步操作,在這個方法被調用之後,委托會進入到內部隊列中,如果池中沒有線程,則創建一個工作線程,把第一個委托放入工作線程。如果繼續放入委托,則池創建新... ...
  • fileStream:操作位元組的,也就是所有的文件都可以拿它去操作 / file / path / streamRead / streamWrite(這兩個都是操作字元的,它所操作的都是文本文件) fileStream 與file的區別,fileStream可以操作大文件,因為fileStream是 ...
  • 返回目錄 應該這樣理解它 非同步,早期開發人員對它有很多誤解,認為不阻塞主線程就是非同步,更有認為不阻塞UI就是非同步,但非同步歸根結底和這兩個東西關係並不大,非同步的出現主要是為了提高線程的利用率,讓可用線程更高,而不是一個線程只做一件事,這件事沒有完成就不去做下麵的事情,這是不正確的,線程應該被解放出來! ...
  • 封裝、繼承、多態,面向對象的三大特性,前兩項理解相對容易,但要理解多態,特別是深入的瞭解,對於初學者而言可能就會有一定困難了。我一直認為學習OO的最好方法就是結合實踐,封裝、繼承在實際工作中的應用隨處可見,但多態呢?也許未必,可能不經意間用到也不會把它跟“多態”這個詞對應起來。在此拋磚引玉,大家討論 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...