gpt4 book ai didi

java - java中的线程和共享计数器

转载 作者:行者123 更新时间:2023-11-29 08:16:47 24 4
gpt4 key购买 nike

我在大学做了这个练习:

编写一个程序,声明一个共享整数计数器,然后创建两个线程,其中一个尝试将计数器递增 1000 次,另一个尝试将计数器递减 1000 次。当每个线程完成循环后,它应该打印出计数器的最终值。 (提示:您需要定义一个 Counter 类。为什么?)您认为输出应该是什么?该程序是否按您预期的那样运行?尝试反复运行该程序,看看是否总是得到相同的结果。

我运行程序时期望最终结果为零,但它实际上每次都输出 0 到 1000 之间的不同数字。谁能告诉我为什么?谢谢。

public class Counter
{
private int val;

public Counter()
{
val = 0;
}

public void increment()
{
val = val + 1;
}

public void decrement()
{
val = val - 1;
}

public int getVal()
{
return val;
}
}

public class IncThread extends Thread
{
private static final int MAX = 1000;
private Counter myCounter;

public IncThread(Counter c)
{
myCounter = c;
}

public void run()
{
for (int i = 0; i < MAX; i++)
{
myCounter.increment();
}
}

}

public class DecThread extends Thread
{
private static final int MAX = 1000;
private Counter myCounter;

public DecThread(Counter c)
{
myCounter = c;
}

public void run()
{
for (int i = 0; i < MAX; i++)
{
myCounter.decrement();
}
}
}

public class Main
{
public static void main(String[] args)
{
Counter c = new Counter();

Thread inc = new IncThread(c);
Thread dec = new DecThread(c);

inc.start();
dec.start();

System.out.println(c.getVal());

}
}

最佳答案

在最低级别,您的代码可能归结为如下内容:

Thread1                Thread2
------- -------
do 1000 times do 1000 times
get reg from [a] get reg from [a]
reg = reg + 1 reg = reg - 1
store reg to [a] store reg to [a]

正因为如此,以及线程可以在它们执行的任何时候停止和启动的事实,你有这样的可能性:

Thread1                Thread2
------- -------
get reg from [a] (0)
get reg from [a] (0)
reg = reg + 1 (1)
reg = reg - 1 (-1)
store reg to [a] (-1)
store reg to [a] (1)

您可以看到,虽然两个线程都刚好完成了千个周期中的一个,并且您希望计数为零,但实际上是一个。

在执行线程之间共享变量时,您需要确保读取、写入和更新是原子的(也有异常(exception),但很少见)。

为此,您应该研究环境中为此目的提供的各种操作(例如语言中的同步功能、互斥量(互斥信号量)或原子变量。

关于java - java中的线程和共享计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4200601/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com