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);
  • 相关阅读:
    Linux软件安装中RPM与YUM 区别和联系
    Linux分区类型EXT2、EXT3、EXT4详解
    【转】SQLServer数据库还原数据库后因孤立用户问题导致无法登陆的处理
    CVE-2018-8045 Joomla内核SQL注入漏洞
    SQL注入漏洞靶场-sqli-labs学习[1-10]
    SQL注入漏洞
    文件包含漏洞
    CSRF的攻击与防御
    XSS漏洞的基本原理
    Linux高性能服务器编程(一):TCP/IP协议族
  • 原文地址:https://www.cnblogs.com/xpvincent/p/7753968.html
Copyright © 2011-2022 走看看