-1

所以我有 3 个线程会尝试找到一个随机生成的数字(每个线程都有自己的范围,即 startNum 和 finishNum)。如果其中一个因为找到数字而停止,我希望所有其他线程也停止。

我读过一个“易失性”布尔值,它显然是一个所有线程共享的布尔值,因此它始终为 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(); 
4

3 回答 3

4

看起来你的三个线程可能在这个类的不同实例中,因此会有 3 个不同的布尔值

尝试将布尔值设为静态,看看它是否改变了任何东西。

(我真的无法为您提供更多帮助,因为我没有看到启动线程的代码)

注意:易失性实际上并不意味着所有线程共享它,它意味着如果所有线程共享它,那么一个线程中的更改将反映在其他线程中的相同变量中。之所以需要它,是因为对于具有独立缓存的多 CPU 机器,一个线程可能会更新其版本,而另一个线程可能不会接收更改,因为它已经缓存了该内存......

于 2013-01-01T01:28:20.907 回答
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 中,参数是按值传递的。所以正在发生的事情是:

  1. 您正在将方法中的值传递startNumrun方法search
  2. search方法将其放入局部变量中。
  3. search方法更新局部变量。
  4. search方法返回,并启动更新的局部变量。
  5. 回到run方法中, 的值startNum没有改变。
于 2013-01-01T01:53:05.727 回答
0

numberFound 未声明为静态,因此每个线程都将独立设置自己的属性值。与同步方法相同 - 每个线程都将获得对自身的锁定,因此实际上同步搜索方法可能不是您想要的。你能更好地解释为什么你同步这个方法吗?这里是关于 volatile 的更多信息:http ://www.javamex.com/tutorials/synchronization_volatile.shtml

以及有关同步和锁定的更多信息:http: //docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

我建议有一个单独的对象,它将成为所有线程之间的共享资源 - 采用这种方法默认锁定将在共享对象本身上执行,因此线程将开始“争夺”对象上的锁定。

于 2013-01-01T01:36:31.860 回答