Comment detail

ワーカスレッドを安全に終了させるまで待機 (Nested Flatten)

Javaのconcurrentユーティリティを使用。スレッドプールはpool.shutdown();で終了します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.util.*;
import java.util.concurrent.*;

class MeApp {
    public static void main(String[] args) throws Exception {
        final ExecutorService pool = Executors.newFixedThreadPool(3);
        try {
            final ArrayList<Future<?> > futures = new ArrayList<Future<?> >();
            final Random random = new Random();
            for (int i = 0; i < 10; ++i) {
                final int id = i;
                final int wait = 5 + random.nextInt(10);
                futures.add(pool.submit(new Runnable() {
                    public void run() {
                        System.out.format("task %d start (%2d sec)\n", id, wait);
                        try {
                            Thread.sleep(wait * 1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                        System.out.format("task %d done\n", id);
                    }
                }));
            }
            for (Future<?> future : futures) {
                future.get(); // wait for task completion
            }
        } finally {
            pool.shutdown();
        }
        System.out.println("completed");
    }
}

oceanさん作バージョンはFuture#get()を用いて各スレッドの終了を待つような実装でした。 もうひとつの解として、ExecutorService#awaitTermination()を用いて、 スレッドプールの各タスクがすべて安全に終了するまでを待つような実装も投稿します。

(今回のプログラムにてExecutorService#submit() を execute()に変えたのは、Futureを使わないことを明示する以外に特に意味はありません。)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class MeApp2 {
    public static void main(String[] args) throws Exception {
        final ExecutorService pool = Executors.newFixedThreadPool(3);
        try {
            final Random random = new Random();
            for (int i = 0; i < 10; ++i) {
                final int id = i;
                final int wait = 5 + random.nextInt(10);
                pool.execute(new Runnable() {
                    public void run() {
                        System.out.format("task %d start (%2d sec)\n", id, wait);
                        try {
                            Thread.sleep(wait * 1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                        System.out.format("task %d done\n", id);
                    }
                });
            }
        } finally {
            pool.shutdown();
            //ここで全タスクの終了を待つ
            pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
        }
        System.out.println("completed");
    }
}

Index

Feed

Other

Link

Pathtraq

loading...