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

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


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

        }


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


撒科打诨
浏览 145回答 1
1回答

至尊宝的传说

在这种情况下,您通常会为您的 Matcher 提供某种工厂,它负责创建适当的线程。在 Java 8 中,您可以使用Supplier接口:public class Matcher {&nbsp; &nbsp; private final Supplier<? extends MatcherThread> threadSupplier;&nbsp; &nbsp; public Matcher(Supplier<? extends MatcherThread> threadSupplier) {&nbsp; &nbsp; &nbsp; &nbsp; this.threadSupplier = threadSupplier;&nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;protected List<Integer> runAll(List<String> clusters, int nthreads) {&nbsp; &nbsp; &nbsp; &nbsp; // …&nbsp; &nbsp; &nbsp; &nbsp; MatcherThread task = threadSupplier.get();&nbsp; &nbsp; &nbsp; &nbsp; task.setSubcluster(subcluster); // refactor to allow setter injection&nbsp; &nbsp; &nbsp; &nbsp; tasks.add(task);&nbsp; &nbsp; &nbsp; &nbsp; // …&nbsp; &nbsp; }}然后,按如下方式实例化匹配器:Matcher matcher = new Matcher(() -> new MaxLength());这假设您添加了一个setSubcluster方法,而不是构造函数注入。或者,您也可以使用Function, 或实现您自己的工厂接口来坚持构造函数注入。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java