使用线程搜索数组中的元素

时间:2014-06-12 07:36:41

标签: java arrays multithreading

我有以下功课要做: 在数组中实现并行搜索指定的元素。使用线程数作为函数参数。 Eeach线程检查自己的数组块大小(ArraySize / NumberOfThreads)。

class MyThread extends Thread {

    final int[] SEARCH_TAB;
    final int RANGE_TAB[][];
    final int SEARCH_VALUE;

    static int searchIndex = -1;
    static boolean isWorking = true;

    int whichThread;

    MyThread(int[] searchTab, int[][] rangeTab, int searchValue, int whichThread) {
        SEARCH_TAB = searchTab; 
        RANGE_TAB = rangeTab;
        SEARCH_VALUE = searchValue;
        this.whichThread = whichThread;
    }

    @Override
    public void run() {
        for (int i = RANGE_TAB[whichThread][0]; i < RANGE_TAB[whichThread][1] && isWorking; ++i) {
            synchronized(this) {
                if (SEARCH_TAB[i] == SEARCH_VALUE) {
                    isWorking = false;
                    searchIndex = i;
                }
            }
        }
    }   
}

class Main {    

    private static int[][] range(int n, int p) {
        int[] quantities = new int[p];
        int remainder = n % p;
        int quotient = n/p;
        int i;
        for (i = 0; i < p; ++i) quantities[i] = quotient;
        i = 0;
        while (remainder != 0) {
        --remainder;
        ++quantities[i];
        ++i;
        }

        int[][] tab = new int[p][2];
        tab[0][0] = 0;
        tab[0][1] = quantities[0];
        for (i = 1; i < p; ++i) {
            tab[i][0] = tab[i-1][1];
            tab[i][1] = tab[i][0] + quantities[i];
        }
        return tab;
    }

    private static int search(int[] searchTab, int numberOfThreads, int searchValue) {
        int[][] rangeTab = range(searchTab.length, numberOfThreads);
        Thread[] threads = new Thread[numberOfThreads];
        for ( int i = 0; i < numberOfThreads; ++i) threads[i] = new MyThread(searchTab, rangeTab, searchValue, i);
        for ( int i = 0; i < numberOfThreads; ++i) threads[i].start();
        return MyThread.searchIndex;
    }

    public static void main(String[] args) {
        int[] tab = {0, 1, 2, 3, 4, 5, 6, 7 , 8, 9, 10};
        int value = 5;
        int valueIndex = search(tab, 1, value);
        if (valueIndex == -1) System.out.println("Not found."); 
        else System.out.println(valueIndex);
    }
}

此代码通常有效,但在实现一个线程时无法找到索引。顺便说一下,我的老师说我的代码太长了,并且有任何建议吗?

我会感激任何帮助。

1 个答案:

答案 0 :(得分:2)

以下代码如何:

public class Searcher implements Runnable {
    private int intToFind;
    private int startIndex;
    private int endIndex;
    private int[] arrayToSearchIn;

    public Searcher(int x, int s, int e, int[] a) {
        intToFind = x;
        startIndex = s;
        endIndex = e;
        arrayToSearchIn = a;
    }

    public void run() {
        for (int i = startIndex; i <= endIndex; i++) {
            if (arrayToSearchIn[i] == intToFind) System.out.println("Found x at index: " + i);
        }
    }
}

public class Starter {
    public static void main(String[] args) {
        int[] a = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
        int numberOfThreads = 5;
        int x = 20;
        findElement(numberOfThreads, x, a);
    }

    private static void findElement(int numberOfThreads, int x, int[] a) {
        int sizeOfa = a.length;
        int range = sizeOfa/numberOfThreads;
        for (int i = 0; i <= numberOfThreads-1; i++) {
            Thread searcher;
            if (i == numberOfThreads-1) {
                searcher = new Thread(new Searcher(x, i*range, sizeOfa-1, a));
            } else {
                searcher = new Thread(new Searcher(x, i*range, i*range+range-1, a));
            }
            searcher.start();
        }
    }
}

您仍然可以优化代码,例如通过在所有线程上拆分数组的其余部分,而不是将其推入最后一个(就像在我的代码中一样)但是这个想法仍然是相同的。

编辑:我认为您的代码存在问题。它只会在数组中显示x的一个外观。如果你在[5,5,5,5,5]中使用五个线程寻找x = 5,你甚至可以知道将返回哪个索引,因为它取决于线程的安排方式。结果将在0到5之间。