繁体   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