Java中的这个程序创建了一个包含15个数字的列表,并创建了3个线程来搜索给定时间间隔内的最大值。我想创建另一个线程,获取这3个数字并获得最大值。但我不知道如何在另一个线程中获取这些值。
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])
{
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){}
}
}
答案 0 :(得分:2)
以下是ExecutorService和ExecutorCompletionService如何解决它:
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;
}
}
}
在此解决方案中,N个线程同时工作,每个线程在数组的部分上。调用者线程负责在到达时收集本地最大值,并找到全局最大值。此解决方案使用java.util.concurrent包中的一些非平凡的并发工具。
如果您更喜欢仅使用原始同步工具的解决方案,那么您应该在工作线程中使用synchronized块,该块设置某些数据成员中的最大值,然后通知收集器线程。收集器线程应处于循环中,等待通知,然后检查新数字,并在需要时更新全局最大值。这种“消费者生产者”模式需要仔细同步。
答案 1 :(得分:1)
根据您拥有的代码,最简单的解决方案是将主线程连接到每个实例线程,然后从中获取最大值以进行比较。像这样:
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){
}
答案 2 :(得分:0)
尝试实现Callable,而不是实现Runnable,它能够返回结果。给出here的教程是描述如何执行此操作的良好来源。
解决问题的另一种方法可能是创建一个对象,每个apple
实例(不知道你为什么称它为此)可以在对象中注册其最大值。这个新类可以传递到每个apple
构造函数中,然后apple
可以调用一个方法,将自己的最大值传递给它。
例如:
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
}
}
关于确保与其他线程协调有几个问题,我会留给你,因为有一些有趣的事情要考虑。