为了账号安全,请及时绑定邮箱和手机立即绑定

我应该如何设计我的线程,以便我不需要实例化一个泛型?

我应该如何设计我的线程,以便我不需要实例化一个泛型?

撒科打诨 2021-09-29 15:04:19
我有几个使用不同比较方法的线程类。我已经将它们实现为扩展抽象类。例如,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();    }}现在,我想要一个可以运行任一线程的类。我的第一个想法是让这个类通用,但是将工作分配给线程需要实例化它们。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);        }我如何重新设计我的类,这样就不需要实例化泛型类型,但我仍然可以在比较函数之间轻松切换?
查看完整描述

1 回答

?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

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


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);

        // …


    }


}

然后,按如下方式实例化匹配器:


Matcher matcher = new Matcher(() -> new MaxLength());

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


查看完整回答
反对 回复 2021-09-29
  • 1 回答
  • 0 关注
  • 144 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信