【问题标题】:Java Threads (Race Condition)Java 线程(竞争条件)
【发布时间】:2015-08-20 12:47:43
【问题描述】:

我对以下代码有疑问。在这种情况下,我希望静态变量“a”和“b”都会发生竞争条件,并且期望这两个变量的输出都小于 1000。但是,当我执行以下代码时,没有观察到预期的行为显示,即 b 的输出始终为 1000。但是,当我取消注释用箭头标记的行并执行以下代码时,两个变量都观察到竞争条件,即变量“a”和“b”的输出是少于1000。同样需要帮助。如果我错过或忽略了线程的任何基本或基本概念,请原谅我,考虑到我仍然是 Java 线程的新手!!!

public class SampleRace {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SampleRace1 a = new SampleRace1();
        SampleRace1 b = new SampleRace1();
        Thread t1 = new Thread(a);
        Thread t2 = new Thread(b);
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //System.out.println(SamapleLoop.a); // <---------------------
        System.out.println(SampleRace1.b);
    }

}

class SamapleLoop {
    public static int a = 0;
    public static void loop() {
        a++;
    }
}

class SampleRace1 implements Runnable {
    public static int b = 0; 
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 1; i <= 500; i++) {
            //SamapleLoop.loop(); // <------------------------
            b++;
        }
    }

}

【问题讨论】:

标签: java multithreading race-condition


【解决方案1】:

尝试将 500 增加到 500.000.000,或者在循环中执行更复杂的操作。线程 a 有可能在线程 b 甚至启动之前运行完成 - 所以它们最终会按顺序运行,而不是并行运行。

您也可以每隔几个周期调用Thread.yield 以放弃您的时间片并让其他线程运行。

【讨论】:

  • 是的..那行得通..似乎 500 对于线程来说太简单了。使用 5000 在循环中,我可以以任何方式观察比赛条件。谢谢@dcastro !!!
【解决方案2】:

如果你愿意,我可以建议一个更合适的比赛条件

import java.util.concurrent.atomic.AtomicInteger;

/*
 * author: Atom Karinca
 */

/*
 * Run this program multiple times to see the output.
 * How does the result vary? Why does that happen?
 *
 */
class Racer extends Thread {    
    private static final int NUM_ITERS = 1000000;

    public void run() {
        for(int j = 0; j < NUM_ITERS; j++) {
            RaceCondition.sum();
        }
    }    
}

public class RaceCondition {
    public static long sum = 0;


    // What happens when you make this method "synchronized"?
    // Do you still see the bug?    
    //synchronized 
    public static void sum() {
        sum = sum + 1;
    }

    public static void main(String[] args) throws InterruptedException {        
        Racer leftAdder = new Racer();
        Racer rightAdder = new Racer();

        leftAdder.start();
        rightAdder.start();

        // wait for the threads to finish
        leftAdder.join();
        rightAdder.join();

        System.out.println("Sum: " + sum);
    }
}

【讨论】:

    猜你喜欢
    • 2016-10-12
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 2010-11-21
    相关资源
    最近更新 更多