如何并行运行不同的方法

use*_*452 6 java parallel-processing multithreading

我有一个java方法,它包含5种不同的内部方法.为了提高性能,我想平行地调用这些方法.

例如,使用线程运行method1,method2,... method5并行.

private void getInformation() throws SQLException,
            ClassNotFoundException, NamingException {
    method1();
    method2();
    method3();
    method4();
    method5();
}
Run Code Online (Sandbox Code Playgroud)

但所有这5种方法都有不同的业务逻辑.

lre*_*der 15

做这样的事情:

  1. 对于每个方法,创建一个包装该方法的Callable对象.
  2. 创建一个Executor(一个固定的线程池执行器应该没问题).
  3. 将所有Callables放在一个列表中,并使用Executor调用它们.

这是一个简单的例子:

public void testThread()
{

   //create a callable for each method
   Callable<Void> callable1 = new Callable<Void>()
   {
      @Override
      public Void call() throws Exception
      {
         method1();
         return null;
      }
   };

   Callable<Void> callable2 = new Callable<Void>()
   {
      @Override
      public Void call() throws Exception
      {
         method2();
         return null;
      }
   };

   Callable<Void> callable3 = new Callable<Void>()
   {
      @Override
      public Void call() throws Exception
      {
         method3();
         return null;
      }
   };

   //add to a list
   List<Callable<Void>> taskList = new ArrayList<Callable<Void>>();
   taskList.add(callable1);
   taskList.add(callable2);
   taskList.add(callable3);

   //create a pool executor with 3 threads
   ExecutorService executor = Executors.newFixedThreadPool(3);

   try
   {
      //start the threads and wait for them to finish
      executor.invokeAll(taskList);
   }
   catch (InterruptedException ie)
   {
      //do something if you care about interruption;
   }

}

private void method1()
{
   System.out.println("method1");
}

private void method2()
{
   System.out.println("method2");
}

private void method3()
{
   System.out.println("method3");
}
Run Code Online (Sandbox Code Playgroud)

确保每个方法不共享状态(如同一个类中的常见可变字段),否则可能会出现意外结果.Oracle为Java Executors提供了很好的介绍.此外,如果你在java中做任何类型的线程,这本书很棒.


小智 7

我有类似的要求。在特定操作中,我必须调用一组验证器方法,这些方法又验证某些组件。每个验证器过去都需要花费一定的时间,必须减少时间并决定以异步方式调用它。

事实上有很多方法可以实现它,这是我解决的方法之一。

由于验证器大多不返回任何值,因此利用了 Runnable 类 lambda。在下面的示例中additionmultiplysubtraction方法将被异步且并行地调用。

public class MultiThreading {

        public static void addition() {
            System.out.println("Addition");
        }

        public static void multiply() {
            System.out.println("multiplication");
        }

        public static void subtraction() {
            System.out.println("subtraction");
        }

        public static void main(String[] args) {
            ExecutorService executor = Executors.newCachedThreadPool();

            Runnable callMultiply = () -> multiply();  //Create Runnable reference using lambda
            executor.execute(callMultiply);
            executor.execute(() -> addition()); //inline
            executor.execute(() -> subtraction());
            
            executor.shutdown();
        }
    }
Run Code Online (Sandbox Code Playgroud)


Ale*_*dov 5

要并行运行 method1,请执行以下操作:

Thread t1=new Thread() {
   public void run() {
       method1();
   }
};
t1.start();
Run Code Online (Sandbox Code Playgroud)

为您的所有方法执行此操作。

要等待方法 1 完成,请执行

t1.join();
Run Code Online (Sandbox Code Playgroud)

对于所有其他线程也是如此。

很多人会告诉你使用线程不要扩展线程——所有这些对你来说都没有意义。掌握这种方式,然后才能遵循该建议。