【问题标题】:Unable to go out of wait method无法退出等待方法
【发布时间】:2013-10-31 13:17:33
【问题描述】:

我正在开发一个简单的程序,它将一个包含 10 个元素的整数数组排序到另一个相同长度的数组中。为此,我创建了 10 个线程,每个线程负责从源数组中获取其编号并将其放入新数组中的正确位置。

我有一个抽象类SortThread,它实现了Runnable。我还有两个扩展上述类的子类,SuperSortThread(初始化源数组,对其编号进行排序并打印出数组)和SimpleSortThread(仅对其编号进行排序)。我试图在“超级线程”初始化数组时锁定源数组。然后,我释放了锁。最后,我有一个创建和启动线程的主类。

这是我的代码:

public abstract class SortThread implements Runnable {

    private final int tNumber;
    static int[] source = new int[10];
    static int[] dest;

    public SortThread(int tNumber) {
        this.tNumber = tNumber;
    }

    public final int lessThan() {
    /* Calculates the number of elements of source
         less than myNumber */

        int count = 0;

        for (int i = 1; i < 10; i++)
            if (source[tNumber] > source[i])
                count++;

        return count;
    }

    @Override
    public abstract void run();
}

import static java.lang.Thread.sleep;

public class SuperSortThread extends SortThread {

    private int tNumber;   

    public SuperSortThread(int tNumber) {
        super(tNumber);
        this.tNumber = tNumber;

    }

    private static void printArray(int[] number) {

        System.out.print("\nVector: ");
        for (int i = 0; i < 10; i++)
            System.out.print(number[i] + " ");

    }

    @Override
    public void run() {

        synchronized (source) {

            source[0] = 5;
            source[1] = 7;
            source[2] = 6;
            source[3] = 3;
            source[4] = 8;
            source[5] = 9;
            source[6] = 4;
            source[7] = 0;
            source[8] = 1;
            source[9] = 2;

            dest = new int[10];
            source.notifyAll();

            printArray(source);

            int myNumber = source[tNumber];
            dest[lessThan()] = myNumber;

            try {
                sleep(1000);
            } catch (InterruptedException e) {
                System.err.println("Error in Sleep.");
            }

            printArray(dest);
        }
    }
}

public class SimpleSortThread extends SortThread {

    private int tNumber;

    public SimpleSortThread(int tNumber) throws InterruptedException {
        super(tNumber);
        this.tNumber = tNumber;
    }

    @Override
    public void run() {

        synchronized (source) {
            try {
                source.wait();
            } catch (InterruptedException e) {
                System.out.println("Wait error in simple thread");
            }

            int myNumber = source[tNumber];
            dest[lessThan()] = myNumber;
        }
    }
}

由于某种原因,“简单线程”被永久锁定在等待状态。会是什么?

【问题讨论】:

  • 也许你的SuperSortThread.run() 是在SimpleSortThread.run() 之前调用的。所以你进入 wait() 但任务已经完成并且 notifyAll() 丢失了..

标签: java arrays multithreading synchronized


【解决方案1】:

如果SuperSortThreadSimpleSortThread 之前运行(或者更具体地说是source.notifyAll();source.wait(); 之前运行),那么当您尝试等待时,没有任何东西可以通知您。你将永远等待。

这称为race condition。您可能应该在通知后设置一个标志,以告诉其他线程您已经通知过,这样它就不会等待。

另外,SimpleSortThread 依赖于 SuperSortThread。没有它你就无法运行它。

最后,可能也是最重要的一点,您究竟想用waitnotify 来完成什么?我看不出你想要它做什么。

【讨论】:

  • 我相信 notifyAll 会唤醒尚未处于等待区的线程。我修复了它,改变了同步调用的顺序并使同步块更接近。
【解决方案2】:

评论 - 它肯定会等待。您正在从 SuperSortThread 发出通知,并且您再次等待 simpleSortThread。你可以等待一些事情是真实的,比如

while(flag){ source.wait()}

并从其他线程设置标志的值。
你等待某事发生,然后如果发生了,你就开始执行一些任务。你什么都不等

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 2017-07-03
    • 2013-11-12
    相关资源
    最近更新 更多