问题描述
我有如下三种方法的类
public class MyRunnable implements Runnable {
@Override
public void run() {
// what code need to write here
//to call the specific methods based on request types
}
public int add(int a, int b){
return a+b;
}
public int multiply(int a , int b){
return a*b;
}
public int division(int a , int b){
return a/b;
}
}
和我的主要班级一样受到打击在这里r.multiply(),add()和divide()方法将按顺序执行,但是我想以多线程方式执行它们,因此我可以更快地得到结果.如何基于输入动态调用类的方法.如何传递给线程以及如何将结果从线程返回给调用线程.
and my main class as blowhere r.multiply(), add() and division() methods will be executed sequentially, but i want to execute them in multi-threaded way hence i can get the result faster. how to call a method of a class dynamically based on inputs. how to pass to thread and how to return result from thread to calling thread.
public class ThreadDemo {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
// how to do below calculation using multihtreading
// how to call a method and how to get result of a thread of same class
int result = r.multiply(1, 2) + r.add(4, 5) + r.division(10, 5);
System.out.println(result);
int newResult = r.add(20, 50);
System.out.println(newResult);
}
}
推荐答案
多线程会减慢该应用程序的速度(因为每个步骤的处理量很小,不足以证明跨线程分配工作的开销).应用程序可能在您仍然感觉不到之前就完成了.
Multi-threading would slow down this application (because the amount of processing per step is far to small to justify the overhead of distributing the work across threads), the application probably finishes well before you perceive it anyway.
假设这是您可以编写的简化示例
Assuming it's a simplified example you can write
MyRunnable r = new MyRunnable();
Executor exec = Executors.newFixedThreadPool(3);
CompletableFuture<Integer> mult = CompletableFuture.runAsync(() -> r.multiply(1, 2),exec );
CompletableFuture<Integer> add = CompletableFuture.runAsync(() -> r.add(4, 5) ,exec);
CompletableFuture<Integer> div = CompletableFuture.runAsync(() -> r.division(10, 5),exec);
CompletableFuture<Integer> result = mult.thenCombine(add, (multRes,addRes) -> multRes+addRest)
.thenCombine(div, (total,divRes) -> total+divRes);
int answer = result.join();
更新为什么使用显式定义的执行器?
UPDATE Why use an explicitly defined Executor?
-
它向读者展示了如何明确定义执行程序(替代方法很简单)
It shows readers how to explicitly define an executor (the alternative is straightforward)
通过将Executor定义为变量,您可以通过仅更改变量分配(不必重构所有方法)在Common ForkJoinPool(或任何其他执行程序类型)之间切换.例如
By defining the Executor as a variable, you can switch between the Common ForkJoinPool (or any other executor type) by changing just that variable assignment (you don't have to refactor all of the methods). E.g.
//ForkJoinPool common
Executor exec = ForkJoinPool.commonPool();
//Expanding thread pool
Executor exec = Executors.newCachedThreadPool();
//Just execute on the current thread
Executor exec = (Runnable r) -> r.run();
默认情况下为CompletableFuture.*异步方法共享公共ForkJoinPool,并行流以及不带特定执行程序的ForkJoinTasks也共享.除非团队的所有成员都仔细考虑何时/不使用Common ForkJoinPool,否则最终可能会意外地将异步I/O操作与CPU绑定处理混入同一池中.
By default CompletableFuture.*Async methods share the Common ForkJoinPool and so do Parallel Streams, along with ForkJoinTasks without a specific executor. Unless all members of the team think carefully about when to / not to use the Common ForkJoinPool you could end up mixing async I/O operations with CPU bound processing in the same pool accidentally.
默认情况下,并行性也设置为Runtime.getRuntime().availableProcessors()-1.这再次可能会或可能不会适合当前的用例(对于某些用户,这可能意味着此示例单线程).如果需要更改默认值,则可以通过系统属性"java.util.concurrent.ForkJoinPool.common.parallelism"进行配置.
Also by default, the parallelism is set to Runtime.getRuntime().availableProcessors() - 1. Which again, may or may not suit the use case at hand (for some users it might mean this example was single threaded). It is configurable via the System Property "java.util.concurrent.ForkJoinPool.common.parallelism", if you need to change the defaults.
这篇关于在Java中使用多线程调用同一类的不同方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!