Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该如何设计我的线程,使我不';不需要实例化泛型?_Java_Multithreading_Generics - Fatal编程技术网

Java 我应该如何设计我的线程,使我不';不需要实例化泛型?

Java 我应该如何设计我的线程,使我不';不需要实例化泛型?,java,multithreading,generics,Java,Multithreading,Generics,我有几个线程类,它们使用不同的比较方法。我将它们实现为一个抽象类的扩展。比如说, public abstract class MatcherThread implements Runnable{ List<String> clusters; int output; public MatcherThread(List<String> clusters){ this.clusters = clusters; } pu

我有几个线程类,它们使用不同的比较方法。我将它们实现为一个抽象类的扩展。比如说,

public abstract class MatcherThread implements Runnable{
    List<String> clusters;
    int output;

    public MatcherThread(List<String> clusters){
        this.clusters = clusters;
    }

    public void run()
    {
        for(List<String> c: clusters) {
            compare(c);
        }
    }

    public int getOutput(){
       return output;
    }

    protected abstract void compare(String c);
}

public class MaxLength extends MatcherThread{
    public MaxLength(List<String> clusters){
      super(clusters);
      this.output = Integer.MAX_VALUE;
    }

    protected void compare(String c){
      if(c.length() > output) output = c.length();
    }
}

public class MinLength extends MatcherThread{
    public MinLength(List<String> clusters){
      super(clusters);
      this.output = 0;
    }

    protected void compare(String c){
      if(c.length() < output) output = c.length();
    }
}
公共抽象类MatcherThread实现可运行{
列出集群;
整数输出;
公共匹配线程(列表集群){
this.clusters=集群;
}
公开募捐
{
用于(列表c:集群){
比较(c);
}
}
公共int getOutput(){
返回输出;
}
受保护的抽象空比较(字符串c);
}
公共类MaxLength扩展MatcherThread{
公共最大长度(列表群集){
超级(集群);
this.output=Integer.MAX_值;
}
受保护的空比较(字符串c){
如果(c.length()>output)output=c.length();
}
}
公共类MinLength扩展MatcherThread{
公共最小长度(列表群集){
超级(集群);
这个输出=0;
}
受保护的空比较(字符串c){
如果(c.length()
现在,我想要一个可以运行任意线程的类。我的第一个想法是使这个类成为泛型的,但是将工作分配给线程需要实例化它们

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Matcher<T extends MatcherThread>{

     protected List<Integer> runAll(List<String> clusters, int nthreads) {
        int n = clusters.size();
        int poolSize = nthreads;
        int step = n/poolSize;
        ExecutorService es = Executors.newFixedThreadPool(poolSize);
        List<T> tasks = new ArrayList<T>();
        for (int i = 0; i < poolSize; i++) {
            int start = i*step;
            int end = i == poolSize -1 ? n: (i+1)*step;

            List<List<String>> subcluster = new ArrayList<List<String>>(){{
                for (int ind=start; ind < end; ind++) add(clusters(ind));
            }};

            T task = new T(subcluster); //This is not allowed.
            tasks.add(task);
        }
        CompletableFuture<?>[] futures = tasks.stream().map(task -> CompletableFuture.runAsync(task, es)).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(futures).join();
        es.shutdown();

        List<Integer> output = new List<Integer>();
        for(T t : tasks) {
            output.add(t.getOutput());
        }
        return output;
    }
}
import java.util.*;
导入java.util.concurrent.CompletableFuture;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类匹配器{
受保护的列表runAll(列表集群、int-nthreads){
int n=clusters.size();
int poolSize=nthreads;
int step=n/池大小;
ExecutorService es=Executors.newFixedThreadPool(池大小);
列表任务=新建ArrayList();
对于(int i=0;iCompletableFuture.runAsync(任务,es)).toArray(CompletableFuture[]::新建);
CompletableFuture.allOf(futures.join();
es.shutdown();
列表输出=新列表();
for(T:tasks){
add(t.getOutput());
}
返回输出;
}
}

我如何重新设计我的类,以便不必实例化泛型类型,但我仍然可以轻松地在比较函数之间切换?

在这种情况下,您通常会向Matcher提供某种工厂,负责创建适当的线程。在Java 8中,您可以使用以下接口:

public class Matcher {

    private final Supplier<? extends MatcherThread> threadSupplier;

    public Matcher(Supplier<? extends MatcherThread> threadSupplier) {
        this.threadSupplier = threadSupplier;
    }

     protected List<Integer> runAll(List<String> clusters, int nthreads) {

        // …
        MatcherThread task = threadSupplier.get();
        task.setSubcluster(subcluster); // refactor to allow setter injection
        tasks.add(task);
        // …

    }

}

这假设您添加了一个
setSubcluster
方法,而不是构造函数注入。或者,您也可以使用或实现自己的factory接口来坚持构造函数注入。

与您的问题无关,但是如果您想从示例中删除一些“不太有趣”的代码,可以通过库生成子集群。例如,从
Matcher matcher = new Matcher(() -> new MaxLength());