簡體   English   中英

如何使這個Java代碼正常運行? [多線程,競爭條件]

[英]How do I make this Java code operate properly? [Multi-threaded, race condition]

我從學生那里得到了這個代碼,由於涉及x++x--的競爭條件,它無法正常工作。 他添加了synchronizedrun()方法試圖擺脫這個bug,但顯然這只會排除線程在同一個對象上輸入run() (這在一開始就不是問題)但不會阻止獨立的對象從同時更新相同的靜態變量x

public class DataRace implements Runnable {
  static volatile int x;

  public synchronized void run() {
    for (int i = 0; i < 10000; i++) {
          x++;
          x--;
    }
  }

  public static void main(String[] args) throws Exception {
    Thread [] threads = new Thread[100];

    for (int i = 0; i < threads.length; i++)
        threads[i] = new Thread(new DataRace());
    for (int i = 0; i < threads.length; i++)
        threads[i].start();
    for (int i = 0; i < threads.length; i++)
        threads[i].join();

    System.out.println(x); // x not always 0!
  }
}

由於我們不能在x同步(因為它是原始的),我能想到的最好的解決方案是創建一個新的靜態對象,如static String lock = ""; 並將x++x--包含在synchronized塊中,鎖定lock 但這似乎很尷尬。 有沒有更好的辦法?

使用AtomicInteger可以實現您想要的功能,並明確表示對x進行操作的意圖是原子的。 經過以下幾次運行后,我每次都得到0

import java.util.concurrent.atomic.AtomicInteger;

public class DataRace implements Runnable {
    static volatile AtomicInteger x = new AtomicInteger(0);

    public void run() {
        for (int i = 0; i < 10000; i++) {
            x.incrementAndGet();
            x.decrementAndGet();
        }
    }

    public static void main(String[] args) throws Exception {
        Thread[] threads = new Thread[100];

        for (int i = 0; i < threads.length; i++)
            threads[i] = new Thread(new DataRace());
        for (int i = 0; i < threads.length; i++)
            threads[i].start();
        for (int i = 0; i < threads.length; i++)
            threads[i].join();

        System.out.println(x); // x **is now** always 0!
    }
}

AtomicInteger正是您的目標。

變量x是靜態的並且駐留在類中,因此應該在該類上同步對它的訪問:要么創建靜態方法,要么在DataRace.class上使用synchronized塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM