开发者

make a thread which recieves values from other threads

This program in Java creates a list of 15 numbers and creates 3 threads to search for the maximum in a given interval. I want to create another thread that takes those 3 numbers and get the maximum. but i don't know how to get those values in the other thread.

public class apple implements Runnable{

String name;
int time, number, first, last, maximum;
int[] array = {12, 32, 54 ,64, 656, 756, 765 ,43, 34, 54,5 ,45 ,6 , 5, 65};


public apple(String s, int f, int l){
    name = s;
    first = f;
    last = l;
    maximum = array[0];
}



public void run(){
    try{

        for(int i = first; i < last; i++ )
        {

            if(maximum < array[i开发者_StackOverflow])
            {
                maximum = array[i];
            }
        }

        System.out.println("Thread"+ name + "maximum = " + maximum);

    }catch(Exception e){}
    }



public static void main(String[] args){
    Thread t1 = new Thread(new apple("1 ", 0, 5));
    Thread t2 = new Thread(new apple("2 ", 5, 10 ));
    Thread t3 = new Thread(new apple("3 ", 10, 15));

    try{

        t1.start();
        t2.start();
        t3.start();
        }catch(Exception e){}

}

}


Here is how ExecutorService and ExecutorCompletionService can solve it:

public class MaxFinder {
    private int[] values;
    private int threadsCount;

    public MaxFinder(int[] values, int threadsCount) {
        this.values = values;   
        this.threadsCount = threadsCount;
    }

    public int find() throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(threadsCount);
        ExecutorCompletionService<Integer> cs = new ExecutorCompletionService<Integer>(executor);

        // Split the work
        int perThread = values.length / threadsCount;       
        int from = 0;
        for(int i = 0; i < threadsCount - 1; i++) {
            cs.submit(new Worker(from, from + perThread));
            from += perThread;
        }
        cs.submit(new Worker(from,values.length));

        // Start collecting results as they arrive
        int globalMax = values[0];
        try {           
            for(int i = 0; i < threadsCount; i++){
                int v = cs.take().get();
                if (v > globalMax)
                    globalMax = v;
            }
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

        executor.shutdown();
        return globalMax;
    }

    private class Worker implements Callable<Integer> {
        private int fromIndex;
        private int toIndex;

        public Worker(int fromIndex, int toIndex) {
            this.fromIndex = fromIndex;
            this.toIndex = toIndex;
        }

        @Override
        public Integer call() {
            int max = values[0];
            for(int i = fromIndex; i<toIndex; i++){
                if (values[i] > max)
                    max = values[i];
            }
            return max;
        }       
    }
}

In this solution, N threads work concurrently, each on its portion of the array. The caller thread is responsible for gathering the local maximums as they arrive, and find the global maximum. This solution uses some non-trivial concurrency tools from java.util.concurrent package.

If you prefer a solution that only uses primitive synchronization tools, then you should use a synchronized block in the worker threads, that sets the maximum in some data member and then notifies the collector thread. The collector thread should be in a loop, waiting for notification and then examining the new number, and updating the global maximum if needed. This "consumer producer" model requires careful synchronization.


Based on the code you have, the simplest solution is to join the main thread to each instance thread and then get the max value from them for comparison purposes. Like so:

int globalMax;

try{

    t1.start();
    t2.start();
    t3.start();

    t1.join();
    globalMax = t1.maximum;

    t2.join();
    if (t2.maximum > globalMax) {
        globalMax = t2.maximum;
    }

    t3.join();
    if (t3.maximum > globalMax) {
        globalMax = t3.maximum;
    }
} catch(Exception e){
}


Instead of implementing Runnable, try implementing Callable, which is capable of returning a result. The tutorial given here is a good source for describing how to do this.

Another approach to your problem could be to create an object which each apple instance (not sure why you've called it this) could register its maximum with the object. This new class could be passed into each apple constructor, then the apple could call a method, passing its own maximum into this.

For instance:

public class MaximumOfMaximumsFinder implements Runnable {
    private List<Integer> maximums = new ArrayList<Integer>();

    public void registerSingleMaximum(Integer max) {
        maximums.add(max);
    }

    public void run() {
         // use similar logic to find the maximum
    }
}

There are several issues around making sure this is coordinated with the other threads, I'll leave this to you, since there's some interesting things to think about.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜