0

オンラインのさまざまな場所への膨大な数の呼び出しを行うファイルを作成しています (残念ながら、これは要件の一部です)。

私の質問は次のようなものです:

メインメソッドがあり、他のメソッドを呼び出したいとしましょう:

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

1 つのクラスを使用する必要がある場合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 needs an instance of Runnable, so what you can do is create a class which implements Runnable and you pass the command that it has to respond to, then depending upon the command you choose which method to call.

public class MyRunnable implements Runnable {

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

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

One disadvantage of this approach is that your run method has too long a list of if else to check which method to invoke.

Benefit is that you don't create unnecessary class if all the methods are related to one class and placing them in separate classes doesn't make sense.

Another approach is to have separate class for every method as suggested by Gray, instead of you directly creating instance of specific class you can use Factory Pattern to create and instance for you.

于 2012-06-01T18:54:40.510 に答える
1

膨大な数の呼び出しを行う必要がある場合、最善の解決策は、スレッド プールをインスタンス化し、それをすべてのタスクに使用することです。後で、マシンに搭載されているプロセッサ/コアの数に応じて調整します。を使用した非常に簡単な実装を次に示します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 を使用することを提案しましたが、Runnable は結果を返さず、チェック例外をスローできないため、callable を使用することをお勧めします。コードをより適切に編成し、例外をスローしたり、メソッドから値を返すことができるようにするには、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. executor サービスを使用する必要があるため、join を呼び出さないでください。

  4. これはネットワーク ジョブであり、しばらくしてから切断する必要があるため、future.get(timeout) を使用します。

于 2012-06-02T06:50:55.037 に答える