如何并行运行不同的方法

时间:2013-08-10 14:29:31

标签: java multithreading parallel-processing

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

e.g。使用thread运行method1,method2,... method5并行。

private void getInformation() throws SQLException,
            ClassNotFoundException, NamingException {
    method1();
    method2();
    method3();
    method4();
    method5();
}

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

6 个答案:

答案 0 :(得分:14)

做这样的事情:

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

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

    确保每个方法不共享状态(如同一个类中的常见可变字段),否则可能会出现意外结果。 Oracle提供a good introduction to Java Executors。另外,如果您在java中进行任何类型的线程,this book都很棒。

答案 1 :(得分:3)

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

Thread t1=new Thread() {
   public void run() {
       method1();
   }
};
t1.start();

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

要等待method1完成,请执行

t1.join();

等所有其他线程。

很多人会告诉你使用threadpool 不会扩展Thread - 所有这些对你来说都没什么意义。掌握这种方式,然后才遵循这些建议。

答案 2 :(得分:0)

您可以在Java中使用高级并发工具 - 线程池。但无论如何,您必须创建Runnable对象(任务),然后使用线程池的方法 - invokeAll()。请查看Oracle concurrency tutorial

答案 3 :(得分:0)

看看java.util.concurrent http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html 和教程: http://docs.oracle.com/javase/tutorial/essential/concurrency/ 基本上,你将不得不创建一个executorserice,一些扩展Runnable的类,并调用它们

答案 4 :(得分:0)

你必须使用5个不同的线程来并行执行你的方法,代码并不难,但很无聊。

您可能希望了解Gpars Tasks,这使得编写并行代码变得更加轻松和愉快。

http://gpars.org/1.0.0/guide/guide/dataflow.html#dataflow_tasks

答案 5 :(得分:0)

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

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

由于验证器通常不返回任何值,因此可以利用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();
        }
    }