[英]How do I implement a multi-threaded variable that I can safely increment using Java?
在我的程序中,我有一个线程将供应变量递增2,然后另一个线程从供应类中获取随机数量的供应。 供应类最多只能存储5个值,并且由于睡眠和供应请求是随机的,因此供应计数可以超过其最大限制。
我要确保的是它没有超过这个限制。
有一个更好的方法吗?
(伪代码)
这是代码:
private int MAX = 5;
private int supply = 0;
public void run()
{
while(true) {
supply = supply + 2;
if(supply > MAX)
supply = MAX;
}
}
您可以使用公共同步的incSupply()方法来增加供应变量:
public synchronized void incSupply()
{
// Code borrowed from Jean-Bernard Pellerin.
int temp = supply + 2;
if (temp > MAX)
temp = MAX;
supply = temp;
}
请注意,对于从'supply'变量读取/写入的其他方法,您还需要使用synchronized。
int temp = supply + 2;
if (temp > MAX)
temp = MAX;
supply = temp;
但这仍然不是线程安全的。 你应该研究锁和同步。
如果你有多个线程,你应该声明你的公共资源,(意味着其他线程对该变量执行命令)在你的情况下,我猜是供应,如同步。 并使用细粒度同步
synchronized(this) {
supply = supply+2
}
我不完全理解你的问题的这一部分: and the other thread takes a random number of supply from the supply class
。 这是否意味着消费线程可以从供应类中获取随机数量的值,或者是随机数的值?
在任何情况下,您都有一个需要互斥访问的资源,因此您需要确保只有一个线程可以修改它。 在java中,这可以通过在被修改的实例上请求内部锁来轻松完成,只有一个线程可以在任何给定时间保持此锁。 现在,当一个线程遇到一个synchronized
块时(根据Stelsavva的例子),它会自动尝试在this
代表的任何一个实例上获得内部锁,并保持它直到块的结尾。 如果任何其他线程遇到该块,而另一个线程持有该锁,则它将等待另一个线程释放该锁。
因此,块的执行是同步的,你不会遇到交错问题。
使用具有五个许可证的信号量 。 有点违反直觉,我认为许可证代表了存储供应的许可,因此第一个线程需要获得存储供应品的许可证。 当第二个线程获取耗材时,它会释放许多许可证。
最简单的解决方案是使用AtomicInteger而不会遇到同步增量的麻烦:
private int MAX = 5;
private AtomicInteger supply = new AtomicInteger(0);
public void run()
{
while(true) {
if(supply.addAndGet(2) > MAX)
supply.set(MAX);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.