gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 07:44:41 24 4
gpt4 key购买 nike

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

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

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

最佳答案

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

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 方法,而不是构造函数注入(inject)。或者,您也可以使用 Function ,或实现您自己的工厂接口(interface)以坚持构造函数注入(inject)。

关于java - 我应该如何设计我的线程,以便我不需要实例化泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52416677/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com