我想用泛型(我第一次嘗試使用泛型)和使用ExecutorService來實現「TaskExecutor」。帶參數的Callable lambda表達式
這裏是我的 「的TaskExecutor」 類:
public class ExecuteAlerterTask<T> {
public List<T> process(String executorName, Callable<T> task) throws ExecutionException, InterruptedException {
final ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat(executorName + "-%d")
.setDaemon(true)
.build();
ExecutorService executor = Executors.newFixedThreadPool(10, threadFactory);
Collection<Future<T>> futures = new ArrayList<>();
IntStream.range(1, 10).forEach(i -> {
Future<T> future = executor.submit(task);
futures.add(future);
});
List<T> result = new ArrayList<>();
for (Future<T> f : futures) {
result.add(f.get());
}
executor.shutdown();
return result;
}
}
這是我的方式來運行它:
@Test
public void process() throws Exception {
Callable<String> callable =() -> "Do something on ";
ExecuteAlerterTask<String> executeAlerterTask = new ExecuteAlerterTask<>();
List<String> result = executeAlerterTask.process("TaskName", callable);
result.forEach(System.out::println);
}
這裏是我的問題: 如何寫我的贖回,這會接受論點i at a line:
Future<T> future = executor.submit(task);
E.g.所需結果將是:
Do something on 1
Do something on 3
Do something on 7
Do something on 2
<...etc...>
如果別的東西是錯我的代碼 - 請讓我知道。上述
編輯
刪除工具可贖回
代碼是我真正想要做的抽象:
- IntRange真的被設置批次,其中從SQL獲取數據的。可調用 確實實現瞭如何處理這些SQL批處理的邏輯。
EDIT2
所有的建議後,我已經下面的解決方案:
public class ExecuteAlerterTask<T> {
public List<T> process(String executorName, Collection<Callable<T>> task) throws ExecutionException, InterruptedException {
final ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat(executorName + "-%d")
.setDaemon(true)
.build();
ExecutorService executor = Executors.newFixedThreadPool(10, threadFactory);
Collection<Future<T>> futures = executor.invokeAll(task);
List<T> result = new ArrayList<>();
for (Future<T> f : futures) {
result.add(f.get());
}
executor.shutdown();
return result;
}
}
而且方式來運行它:
@Test
public void process() throws Exception {
Collection<Callable<String>> tasks = new ArrayList<>();
IntStream.range(1, 10).forEach(i -> {
tasks.add(new Task(i).callable);
});
ExecuteAlerterTask<String> executeAlerterTask = new ExecuteAlerterTask<>();
List<String> result = executeAlerterTask.process("TaskName", tasks);
result.forEach(System.out::println);
}
private class Task {
private int i;
private Callable<String> callable =() -> "Doing something on i: " + i;
private Task(int i) {
this.i = i;
}
}
EDIT3
運行它更簡單的方法:
@Test
public void process() throws Exception {
Collection<Callable<String>> tasks = new ArrayList<>();
IntStream.range(1, 10).forEach(i -> {
tasks.add(() -> "Do something on i: " + i * 2);
});
ExecuteAlerterTask<String> executeAlerterTask = new ExecuteAlerterTask<>();
List<String> result = executeAlerterTask.process("TaskName", tasks);
result.forEach(System.out::println);
}
我想我最終的解決方案非常滿意。謝謝大家!
爲什麼你在不使用'Callable'的時候不使用它? – RealSkeptic
@RealSkeptic好了。這回答瞭如何擺脫T調用的問題() – lapkritinis
它幾乎看起來像要顯示在哪個線程上執行工作,但是您已經以完全反向的方式編寫了代碼。 – Kayaman