0

我在课堂上被问到一个问题,'a 的可能最终值是多少?(假设每条语句是一个执行单元。你不需要在指令级考虑问题。)'。附加信息:

线程 A:a = 3 (A1) 和 a = a + 1 (A2)

线程 B:a = 5 (B1) 和 a = a + 7 (B2)

所以经过一些思考,第一个线程输出应该是 4,第二个线程输出应该是 12。

所以我做了测试脚本,看看这是否正确,输出显示了我预期的线程 A:4 和线程 B:12。

问题是,我应该期待其他值吗?或者,也许我只是错误地执行了这个问题?如果可能,我如何调整此代码以获取其他值?这是一个棘手的问题,还是只有我一个人?

编辑:由于我的家庭作业真的不需要代码,所以让我们专注于此类问题的理论实现。

4

5 回答 5

2

如果您曾经更正此问题以使其真正表现出线程而不是顺序执行,那么正确的答案将是在没有任何类型的同步的情况下,行为是未定义的。

于 2012-09-17T02:58:31.103 回答
2

假设您确实修复了代码以正确实现线程,考虑到今天的 CPU 速度和启动线程/调度的开销,我打赌您不会看到任何并发错误,因为第一个线程或第二个线程将a在另一个有机会开始,所以你可能总是得到 4 和 12 作为结果。

要发生数据竞争,您将需要更多冗长的任务。

于 2012-09-17T05:53:47.560 回答
1

FirstThread您对and的调用SecondThread正在主线程上运行,而不是threadAor threadB。此外,该run()方法什么也不做。

在这个问题中对线程的任何引用都只是误导(噪音),与输出无关。

(还有方法名称FirstThread,并且SecondThread应该以小写字母开头以匹配 Java 约定)

于 2012-09-17T02:49:30.990 回答
1

如果我正确理解您的问题,那么您提供的代码不是作为作业问题的一部分给出的,而是代表您尝试回答它。鉴于此,正如 Tudor 已经指出的那样,即使在正确的实现中,即使您运行该程序几百次,您也可能看不到任何“令人惊讶”的值。通过测试很难发现并发错误。

我理解正确答案的提示如下:假设你正在和你爱的人一起做两道菜作为晚餐。您可以先煮(辣)主菜,然后再煮(甜)沙漠。(无线程)。或者你同时烹饪它们,在两种食谱之间切换。它们都可能指的是平底锅(最初充满空气),一个告诉你用鸡蛋代替锅里的东西,另一个告诉你用油代替里面的东西,然后加入香料。因为你是一个糟糕的厨师(你还没有学习同步)你先放油,然后用鸡蛋代替里面的所有东西,加糖,然后回到第一个食谱并加入香料......味道会怎样像?

于 2012-09-17T09:12:16.223 回答
-1

您可以获得其他值,但您需要做一些事情来使程序执行,因为线程是随机的并且很难控制。您可以尝试我的代码,我认为您的代码有问题,但我不会更改它,好的?

public class Threads implements Runnable
{
    int a = 0;

    public void run() { }

    public int FirstThread()
    {
        a = 3;
        Thread.sleep(2000);
        a = a + 1;

        return a;
    }

    public int SecondThread()
    {
        a = 5;
        a = a + 7;

        return a;
    }
}

或使用这个

public class Threads implements Runnable
{
    int a = 0;

    public void run() { }

    public int FirstThread()
    {
        a = 3;
        a = a + 1;

        return a;
    }

    public int SecondThread()
    {
        a = 5;
        Thread.sleep(2000);
        a = a + 7;

        return a;
    }
}

就试一试吧!!!

于 2012-09-17T02:35:48.127 回答