java資料同步陷阱

來源:互聯網
上載者:User

標籤:

並發,我的理解就是同時運行多個程式。同時,難以避免的就是資料的同步問題,如果資料同步問題處理不好就很容易造成程式出現bug,當然,對於其造成的危害,不加詳述。

首先,來看一個簡單的例子,當然,這個例子也並非是我發現的。

public class StopTread {    private static boolean stopRequested;        static Thread backgroundThread = new Thread(new Runnable() {                 public void run() {            int i = 0;            while(!stopRequested)            {                i++;            }        }    });        public static void main(String[] args) throws InterruptedException    {        backgroundThread.start();        TimeUnit.SECONDS.sleep(1);        stopRequested = true;    }}

造成這個問題的原因在於當主線程修改了stopRequested變數後,後台線程並沒有及時的讀取到最新的值,因此,造成了後台線程會一直運行下去。代碼內容很容易理解,就是通過一個變數來控制線程的停止與運行而已。當stopRequested被主線程設定為true時,後台線程就終止運行。但是,這個程式中並沒有對stopRequested做資料同步處理,這就造成了資料的不安全性,當然,並不是在所有情況都能發生這個資料的不安全性的。但至少理論上是存在,同時,我也花費了很長的時間,類比出了這個不安全性的存在。

根據相關資料解釋其原因為:

while(!stopRequested){    i++;}

被最佳化成了:

if(!stopRequested)    while(true)        i++;

也正是由於這個最佳化導致了程式無法前進執行。

對於解決這個問題的方法有兩種:其一是通過鎖機制,其二是通過volatile修飾符。

方法一:

public class StopTread {    private static boolean stopRequested;        static Thread backgroundThread = new Thread(new Runnable() {                 public void run() {            int i = 0;            while(!stopRequested())            {                i++;            }        }    });        private static synchronized void requestStop()    {        stopRequested = true;    }            private static synchronized boolean stopRequested()    {        return stopRequested;    }        public static void main(String[] args) throws InterruptedException    {        backgroundThread.start();        TimeUnit.SECONDS.sleep(1);        requestStop();    }}

  可以發現,寫方法和讀方法都被同步了,只同步寫方法是不能實現,如果沒有對讀和寫方法都進行同步的話,同步是不會起作用的。

方法二:

public class StopTread {    private static volatile boolean stopRequested;        static Thread backgroundThread = new Thread(new Runnable() {                 public void run() {            int i = 0;            while(!stopRequested)            {                i++;            }        }    });       public static void main(String[] args) throws InterruptedException    {        backgroundThread.start();        TimeUnit.SECONDS.sleep(1);        stopRequested = true;    }}

Volatile的修飾符不執行互斥訪問,但是可以保證一個縣城在讀取該域的時候就講看到最近剛剛被寫入的值。

java資料同步陷阱

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.