在java中使用多线程调用同一类的不同方法

时间:2015-09-24 11:39:57

标签: java multithreading

我有一个类如下,有三种方法

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()和division()方法将按顺序执行,但我想以多线程方式执行它们,因此我可以更快地得到结果。如何根据输入动态调用类的方法。如何传递给线程以及如何将结果从线程返回到调用线程。

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

1 个答案:

答案 0 :(得分:4)

多线程会降低这个应用程序的速度(因为每个步骤的处理量很小,以证明跨线程分配工作的开销),应用程序可能会在您感知之前完成。

假设这是一个简化的例子,你可以写

 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 为什么要使用明确定义的Executor?

  • 它向读者显示如何明确定义执行者(替代方案是直截了当的)

  • 通过将Executor定义为变量,您可以通过仅更改该变量赋值来切换Common ForkJoinPool(或任何其他执行程序类型)(您不必重构所有方法)。 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。* Async方法共享Common ForkJoinPool,Parallel Streams和ForkJoinTasks共享没有特定执行程序。除非团队的所有成员都仔细考虑何时/不使用Common ForkJoinPool,否则您最终可能会在同一个池中意外地将异步I / O操作与CPU绑定处理混合在一起。

  • 同样默认情况下,并行性设置为Runtime.getRuntime()。availableProcessors() - 1.这又可能适合或不适合手头的用例(对于某些用户,它可能意味着这个例子是单线程)。如果您需要更改默认值,可以通过系统属性“java.util.concurrent.ForkJoinPool.common.parallelism”进行配置。