所以我有3个线程会尝试找到一个随机生成的数字(每个线程都有自己的范围,即startNum和finishNum)。如果其中一个因为找到了数字而停止,我希望所有其他的停止同样。
我已经读过一个“volatile”布尔值,它显然是一个所有线程共享的布尔值,因此它总是1个值。
这是我的代码:(注意:如果线程结束而其他人正在进行,如果线程“停止”,因为它的startNumber超过了它的finishNumber,那就没关系了)
private volatile boolean numberFound = false;
public void run()
{
while(startNum < finishNum) //what i'm talking about with the [note]
{
search( startNum);
if(numberFound == true)
{
break;
}
}
}
private synchronized void search(int startNum)
{
for(int i = 0; i < 10; i++)
{
if( startNum != searchNum )
{
startNum++;
}
else if(startNum == searchNum )
{
numberFound = true;
System.out.println( this.currentThread().getName() + " has found the number: " + searchNum );
break;
}
}
}
哦,我也循环了10次,因为我希望程序在每个数字范围(线程)中检查每次10次,然后转移到另一个。
这是根据请求启动线程的main()方法: int randomNum =(int)(Math.random()* 1001);
FindIt t1 = new FindIt(randomNum, 0, 349); //FindIt extends Thread
FindIt t2 = new FindIt(randomNum, 350, 699);
FindIt t3 = new FindIt(randomNum, 700, 1000);
t1.start();
t2.start();
t3.start();
答案 0 :(得分:4)
看起来你的三个主题可能在这个类的不同实例中,因此会有3个不同的布尔值
尝试将布尔值设为静态,看看它是否会发生任何变化。
(我真的无法帮助你,因为我没有看到启动线程的代码)
注意:Volatile实际上并不意味着所有线程共享它,这意味着如果所有线程共享它,那么一个线程中的更改将反映在其他线程中的相同变量中。这是必要的,因为对于具有独立缓存的多CPU机器,一个线程可能会更新它的版本,而另一个线程可能无法获取更改,因为它已经缓存了内存....
答案 1 :(得分:1)
提及numberFound
必须为static
的答案是正确的。关于使用synchronized
进行锁定的问题也是正确的(虽然不清楚你需要锁定这里......)。
但是另一个与并发性无关的错误导致了你的直接问题。
while(startNum < finishNum) {
search(startNum);
if(numberFound == true)
{
break;
}
}
private synchronized void search(int startNum) {
...
if (startNum != searchNum) {
startNum++;
}
...
问题是,您正在递增的startNum
与您在startNum
循环中测试的while
不同。在Java中,参数按值传递。所以发生的事情是:
startNum
方法中的run
值传递给search
方法。search
方法将其放在局部变量中。search
方法更新局部变量。search
方法,并启动更新后的本地变量。run
方法,startNum
的值未发生变化。答案 2 :(得分:0)
numberFound未声明为static,因此每个线程都将独立设置自己的属性值。 与同步方法相同 - 每个线程都会获得一个自身的锁定,所以实际上同步搜索方法可能不是你想要的。你能更好地解释为什么你这个方法同步? 这里更多关于volatile:http://www.javamex.com/tutorials/synchronization_volatile.shtml
以及有关同步和锁定的更多信息: http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
我建议有一个单独的对象,它将成为所有线程之间的共享资源 - 具有这种方法的默认锁定将在共享对象本身上执行,因此线程将开始“争夺”对象的锁定。