无法退出等待方法

时间:2013-10-31 13:17:33

标签: java arrays multithreading synchronized

我正在研究一个简单的程序,它将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;
        }
    }
}

出于某种原因,“简单线程”永久锁定在等待中。它可能是什么?

2 个答案:

答案 0 :(得分:0)

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

这称为race condition。您应该在通知后设置一个标志,告诉另一个线程您已经通知,以便它不会等待。

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

最后,也许最重要的是,您在waitnotify尝试完成了什么?我看不到你想要它做什么。

答案 1 :(得分:0)

评论 - 肯定会等待。你正在从SuperSortThread通知你再次等待simpleSortThread。你可以等待某些事情像

一样真实
while(flag){ source.wait()}

并从其他线程设置flag的值。
你等待某事发生,如果发生这种情况,你就开始执行某项任务。你等不及了