zoukankan      html  css  js  c++  java
  • 基本パターン(単一スレッド)

     

    別スレッドにするタスクの作成

    別にスレッドにしたい処理を、Runnable インタフェースを実装したクラスのrumメソッドに実装する。

    public class TestRunnable implements Runnable {
    
        public void run() {
            // スレッドIDを出力する
            System.out.println(Thread.currentThread().getId());
        }
    }
    

    スレッドの生成とタスクの実行

    ExecutorService クラスを利用して、スレッドの生成・タスクの実行を行う。
    ここでは、「newSingleThreadExecutor」でスレッドを一つのみ生成し、5回タスクを実行している。

    ExecutorService exec = Executors.newSingleThreadExecutor();
    
    for (int i = 0; i < 5; i++) {
         exec.submit(new TestRunnable());
    }
    

    実行結果

    1スレッドのみなので、すべて同じスレッドIDが出力される。

    44
    44
    44
    44
    44
    

    固定数の複数スレッド生成

    newFixedThreadPoolを使用すると、固定数のスレッドを生成できる。

    // 引数に生成するスレッド数を渡す
    ExecutorService exec = Executors.newFixedThreadPool(3);
    
    for (int i = 0; i < 5; i++) {
         exec.submit(new TestRunnable());
    }
    

    3つの固定スレッドを生成したので、3つのスレッドを使いまわしている。

    24
    24
    24
    26
    25
    

    必要に応じて複数スレッド生成

    newCachedThreadPoolを使用すると、必要に応じてスレッドを生成する。
    60秒間使用されなかったスレッドは破棄され、60秒未満であれば再利用される。

     ExecutorService exec = Executors.newCachedThreadPool();
    
     for (int i = 0; i < 5; i++) {
         exec.submit(new TestRunnable());
     }
    
     Thread.sleep(1 * 5000);
     System.out.println("--------5秒後---------");
    
     for (int i = 0; i < 5; i++) {
         exec.submit(new TestRunnable());
     }
    
     Thread.sleep(1 * 70000);
     System.out.println("--------70秒後---------");
    
     for (int i = 0; i < 5; i++) {
         exec.submit(new TestRunnable());
     }
    

    3回に分けて処理を実行。
    最初の実行から、5秒後に実行した処理は同じスレッドを再利用している。
    70秒後の実行では既にスレッドが破棄されて、新しいスレッドが生成されている。

    26
    24
    25
    27
    28
    --------5秒後---------
    24
    27
    28
    25
    26
    --------70秒後---------
    31
    33
    30
    32
    29
    

    実行結果を取得する

    実行結果を返すタスクの作成

    実行結果を返す処理は、Callableインタフェースを実装したクラスのcallメソッドに実装する。

    public class TestCallable implements Callable<Long> {
        public Long call() throws Exception {
            //スレッドIDを返す
            return Thread.currentThread().getId();
        }
    }
    

    タスクの実行と実行結果の取得

    タスクの実行は、結果を返さない場合と同じく ExecutorService を使用するが、
    戻り値としてFutureインタフェースを受け取る。

    List<Future<Long>> list = new ArrayList<Future<Long>>();
    for (int i = 0; i < 10; i++) {
        Future<Long> future = exec.submit(new TestCallable());
        list.add(future);
    }
    
    //Future#getメソッドで結果を取得できる。実行中の場合は終了まで待つ。
    
    for (Future<Long> future : list) {
       try {
           Long id = future.get();
       } catch (InterruptedException e) {
           e.printStackTrace();
       } catch (ExecutionException e) {
           e.printStackTrace();
       }
    }
    

    引数を指定することで、指定した時間だけ実行結果を待つことができる。
    指定した時間を超えると、TimeoutExceptionがスローされる。

    //1秒間だけ待つ。
    Long id = future.get(1, TimeUnit.SECONDS);
  • 相关阅读:
    算法竞赛入门经典习题2-3 韩信点兵
    ios入门之c语言篇——基本函数——5——素数判断
    ios入门之c语言篇——基本函数——4——数值交换函数
    144. Binary Tree Preorder Traversal
    143. Reorder List
    142. Linked List Cycle II
    139. Word Break
    138. Copy List with Random Pointer
    137. Single Number II
    135. Candy
  • 原文地址:https://www.cnblogs.com/xpvincent/p/7753968.html
Copyright © 2011-2022 走看看