5

各スレッドが実行されていることを確認しようとしているマルチスレッドプログラムに取り組んでい30 minutesます。ある場合10 threads、 の各スレッド10は に対して実行する必要があるとし30 minutesます。

以下は私のコードです-

class ThreadTask implements Runnable {
    private final long endTime;

    public ThreadTask(long endTime) {
        this.endTime = endTime;
    }

    @Override
    public void run() {

        while (System.currentTimeMillis() <= endTime) {

            // do something meaningful

        }   
    }
}

public class TestPool {

    public static void main(String[] args) {

        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(1000); 

        long startTime = System.currentTimeMillis();
        long endTime = startTime + (30 * 60 * 1000);

        for (int i = 0; i < threads; i++) {
            service.submit(new ThreadTask(endTime));
        }

        // wait for termination        
        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    }
}

今、私の質問は-

上記のコードは、各スレッドが同時に開始され、実行されていることを保証し30 minutesますか? スレッドを Thread Pool に入れるのにどれくらいの時間がかかるかわかりません。しかし、一部のスレッドの開始が少し遅れて、正確30 minutesに 30 分未満で実行されない可能性があるようです。

各スレッドが同時に開始され、正確に実行される必要があることを探しています30 minutes

4

3 に答える 3

1

簡単な答え: いいえ、すべてのスレッドが正確に同時に開始されるわけではありません (許容範囲によっては、「まったく」無視できる可能性があります)。また、意味のあることによっては、各スレッドが正確に 30 分実行される可能性はほとんどありません (ここでも、時間の粒度がこのアサーションを間違っている可能性があります)。

リード:

  • すべてのスレッドができるだけ近い位置で開始される可能性を最大限に高めるには、最初にスレッドを作成してからエグゼキューターに送信します。Java でのスレッドの作成は、他の言語と同様、コストのかかる操作です。
  • スレッドが正確に 30 分間実行されるようにするには、現在コンストラクターに渡している引数が既に精度に影響を与える可能性があるため (スレッドの作成時間により)、各スレッドが終了時間を計算することをお勧めします。
  • 通常、1000 スレッドのスレッド プールを作成することはお勧めしません (モンスター マシンまたは微積分グリッドで Java を実行する場合を除く)。物理マシンにスレッドと同じ数のコアがない場合、JVM が実行するスレッドを決定するたびにコンテキスト スイッチが発生することに注意してください。

編集

public class TestPool {

    public static void main(String[] args) {

        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(10); 

        long startTime = System.currentTimeMillis();
        long endTime = startTime + (30 * 60 * 1000);

        ThreadTask[] threadTasks = new ThreadTask[threads];
        for (int i = 0; i < threads; i++) {
            threadTasks[i] = new ThreadTask(endTime);
        }

        for (ThreadTask tt : threadTasks) {
            service.submit(tt);
        }

        // wait for termination        
        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    }
}
于 2013-03-05T18:15:43.080 に答える
0

一見すると、これはやや非現実的なマルチスレッド演習プロジェクトのように見えます。しかし、あなたは私がマルチスレッドプログラムに取り組んでいると言います。これは、実際のアプリケーションの背景があることを示唆しています。

その場合:できるという理由だけで1000スレッドを作成しないでください。代わりに、実際に達成したいことを言ってください。

要件について:最小の遅延でほぼ同時にすべてのスレッドを開始するには、次prestartAllCoreThreadsのことができますThreadPoolExecutor// do something meaningfulrunメソッドに含まれるRunnableを送信します。実行時間を30分に制限するには、30分後にshutdownNowを使用してThreadPoolExecutorをシャットダウンするTimerTaskをスケジュールします。ThreadPoolExecutorを作成するときは、必要なスレッド数のオーダーのサイズの固定サイズのBlockingQueueを使用して、送信するジョブが多すぎないようにすることができます。

于 2013-03-05T21:02:53.333 に答える
0

最大の並列処理を実現するために、カウントダウン ラッチの使用を検討してください。基本的に、合計カウント 1 でシングルトン/静的 countdownLatch を作成し、複数のスレッドが同じカウントダウンを待機できるようにすることができます。私がやったことを以下にチェックしてください

スレッドの開始時刻を決定するメイン スレッド。

package mylab.threads;

import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainThread extends TimerTask {

    private static CountDownLatch countDown = new CountDownLatch(1);

    private ExecutorService es = Executors.newCachedThreadPool();

    @Override
    public void run() {

    try {


        Thread1 thread1 = new Thread1();
        thread1.setDoneSignal(countDown);
        es.submit(thread1);

        Thread2 thread2 = new Thread2();
        thread2.setDoneSignal(countDown);
        es.submit(thread2);

        System.out.println("waiting main.. ");
        synchronized(this) {
        this.wait(2000);
        }
        System.out.println("kick off threads..");
        countDown.countDown();

    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    }

}

並行して実行するスレッドを定義する

package mylab.threads;

import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;

public class Thread1 extends TimerTask{

    private CountDownLatch doneSignal = null;

    /**
     * @return the doneSignal
     */
    public CountDownLatch getDoneSignal() {
        return doneSignal;
    }

    /**
     * @param doneSignal the doneSignal to set
     */
    public void setDoneSignal(CountDownLatch doneSignal) {
        this.doneSignal = doneSignal;
    }

    @Override
    public void run() {

    try {
        this.doneSignal.await();
        System.out.println("get going thread 1 -"+new Date().getTime());
        synchronized(this) {
        this.wait(3000);
        }
        System.out.println("Exiting thread 1 - "+new Date().getTime());
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }

}


package mylab.threads;

import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;

public class Thread2 extends TimerTask{

    private CountDownLatch doneSignal = null;

    /**
     * @return the doneSignal
     */
    public CountDownLatch getDoneSignal() {
        return doneSignal;
    }

    /**
     * @param doneSignal the doneSignal to set
     */
    public void setDoneSignal(CountDownLatch doneSignal) {
        this.doneSignal = doneSignal;
    }

    @Override
    public void run() {

    try {
        this.doneSignal.await();
        System.out.println("get going thread 2 -"+new Date().getTime());
        synchronized(this) {
        this.wait(3000);
        }
        System.out.println("Exiting thread 2 - "+new Date().getTime());
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }
}

最後にメインスレッドを実行します。

package mylab.threads;

public class ThreadTest {

    /**
     * @param args
     */
    public static void main(String[] args) {

    MainThread mt = new MainThread();
    mt.run();

    }

}

ここに出力があります

waiting main.. 
kick off threads..
get going thread 1 -1387513662107
get going thread 2 -1387513662107
Exiting thread 1 - 1387513665108
Exiting thread 2 - 1387513665108
于 2013-12-20T04:43:52.407 に答える