0

我正在编写一个文件,该文件在网上对不同位置进行大量调用(遗憾的是,这是要求的一部分)

我的问题是这样的:

假设我有一个 main 方法并想调用其他方法:

public static void main(String args[]){
    //how do I break stuff into threads here
     Thread nameThread1 = new(fileName.DoMethod1(x))
     Thread nameThread2 = new(fileName.DoMethod2(x))
     Thread nameThread3 = new(fileName.DoMethod3(x))
     Thread nameThread4 = new(fileName.DoMethod4(x))
     Thread nameThread5 = new(fileName.DoMethod5(x))
}



           //fileName.java
public static void doMethod1(object){
   //Do Method Stuff
}

public static void doMethod2(object){
   //Do Method Stuff
}

我已经阅读了一些关于如何实现它的指南,但我仍然对执行此操作的精确方法感到困惑。

如果可能的话,有人可以给我看一些例子吗?谢谢!

4

4 回答 4

8

您不能像在您的帖子中那样调用不同的方法。你可以做的是调用不同的类:

public static void main(String args[]){
     Thread nameThread1 = new Thread(new Method1(x));
     nameThread1.start();
     Thread nameThread2 = new Thread(new Method2(x));
     nameThread2.start();
     Thread nameThread3 = new Thread(new Method3(x));
     nameThread3.start();
     Thread nameThread4 = new Thread(new Method4(x));
     nameThread4.start();
     Thread nameThread5 = new Thread(new Method5(x));
     nameThread5.start();
}

public class Method1 implements Runnable {
   private Object obj;
   public Method1(Object obj) {
       this.obj = obj;
   }
   //fileName.java
   public void run(){
      //Do Method Stuff
   }
}

您应该始终考虑使用创建ExecutorService代码来管理这样的作业。例如:

// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.submit(new Method1(x));
threadPool.submit(new Method2(x));
...
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();

如果您必须使用一个类,那么您可以启动一个Runnable使用开关或其他东西的类:

public static void main(String args[]){
     Thread nameThread1 = new Thread(new Method(1, x));
     nameThread1.start();
     Thread nameThread2 = new Thread(new Method(2, x));
     nameThread2.start();
     ...
}
public class Method1 implements Runnable {
   private int which;
   private Object obj;
   public Method1(int which, Object obj) {
       this.which = which;
       this.obj = obj;
   }
   //fileName.java
   public void run(){
       switch(which) {
          case 1:
             doMethod1(obj);
             break;
          case 2:
             doMethod2(obj);
             break;
          ...
       }
    }
    private void doMethod1(Object obj){
       ...
    }
    private void doMethod2(Object obj){
       ...
    }
}

但是执行者或单独的Runnable类会更干净。

于 2012-06-01T18:45:36.657 回答
1

Thread需要一个 的实例Runnable,因此您可以做的是创建一个实现 Runnable 的类,然后传递它必须响应的命令,然后根据您选择调用哪个方法的命令。

public class MyRunnable implements Runnable {

   public MyRunnable(String commandToExecute){
      this.command = commandToExecute;
   }

   public void run() {
      //depending on command call specific methods.
   }
}

这种方法的一个缺点是您的 run 方法的 if else 列表太长,无法检查要调用的方法。

好处是,如果所有方法都与一个类相关并且将它们放在单独的类中没有意义,那么您就不会创建不必要的类。

另一种方法是按照 Gray 的建议为每个方法设置单独的类,而不是直接创建可以用来Factory Pattern为您创建和实例的特定类的实例。

于 2012-06-01T18:54:40.510 回答
1

如果您必须进行大量调用,最好的解决方案是实例化一个线程池并将其用于所有任务。稍后,您根据机器拥有的处理器/内核数量对其进行盘绕调整。这是一个使用 a 的非常简单的实现ThreadPoolExecutor

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class GenericThreadPool {

    private static final int CORE_POOL_SIZE = 3;
    private static final int MAXIMUM_POOL_SIZE = 10;
    private static final long KEEP_ALIVE_TIME = 10;

    private ThreadPoolExecutor threadPool = null;
    private final LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();

    private GenericThreadPool() {
        this.threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                this.queue);

    }

    private static class LazyHolder {
        public static final GenericThreadPool INSTANCE = new GenericThreadPool();
    }

    public static GenericThreadPool getInstance() {
        return LazyHolder.INSTANCE;
    }

    public void execute(Runnable task) {
        this.threadPool.execute(task);
    }

    public void shutdown() {
        this.threadPool.shutdown();
    }


}

要执行任务,您只需创建一个实现Runnable接口的类,获取线程池实例并运行您的作业。

public class MyJob implements Runnable {
   public void run(){
      // Do your job here...
   }
}

GenericThreadPool pool = GenericThreadPool.getInstance();
pool.execute(new MyJob());
于 2012-06-01T19:08:13.643 回答
0

好吧,很多人建议你使用 Runnable,但我建议你使用 Callable,因为 Runnable 不返回结果并且不能抛出检查异常。为了更好地组织代码并能够从方法中抛出异常或返回值,请使用 callable。也为了您的目的,使用一些池执行器来完成这项工作。这是我对设计的看法,-

  1. 编写一个可调用类并根据请求参数调用适当的方法,

    私有类 GetAndProcessResponse 实现 Callable { 私有最终请求请求;私人最终CountDownLatch countDownLatch;

        GetAndProcessResponse(final Request request, final CountDownLatch countDownLatch) {
            this.request = request;
            this.countDownLatch = countDownLatch;
        }
    
        public ProcessedResponse call() {
            try {
                // do a switch case on request params
                // and call appropriate methods.
            } finally {
                countDownLatch.countDown();
            }
        }
    }
    
  2. 使用 countDownLatch 获取作业完成状态。

  3. 不要调用 join,因为你需要使用 executor 服务。

  4. 使用 future.get(timeout) 因为它是一个网络工作,需要一段时间后削减。

于 2012-06-02T06:50:55.037 回答