Java SE7 Gold 取得を目指して (終)

Java SE7 Gold をとりたい…!
===

長かった(?)資格取得への記事も今回で最終回です。
スレッドについての章を進めました。

## 今日のこぼれ話

先日Goldを受験してきました。結果をまとめるとこんな感じです。

* 勉強時間 : 1.5h × 14(記事数)
* 参考書 : オラクル認定資格教科書 Javaプログラマ Gold SE 7(翔泳社)
* 正答率 : 73% (合格ライン 65%)
* 結果 : 合格

とても誇れる正答率ではありませんでしたが、何とか合格でした。リテイクの出る幕はありません!
参考書のペース配分を誤り最後の模試には手を付けられないなどありましたが、合格にこぎつけられたのはQiitaのおかげでしょうね。
アウトプット+誰かに見られている感大事。
名刺にロゴつけてもらおうかな…。でも業務でJava久しくやってないな…。

## 本日知ったこと(11章)

* スレッドの作成
  * Threadクラスでスレッド作成
     1. Threadクラスを継承したサブクラスを定義
     1. `run()`をオーバーライド
     1. 定義したクラスのインスタンス化
     1. `start()`を呼び出す (→ Java実行環境がrun()を呼び出す) ※`run()`を直接呼んでもスレッドは作成されない
  
  * Runnableインタフェースでスレッド作成
     1. Rnnableインタフェースを実装したクラスを定義 
     2. `run()`をオーバーライド
     3. 定義したクラスをインスタンス化してThreadクラスのコンストラクタに渡す
     4. Threadの`start()`を呼び出す ※`run()`を直接呼んでもスレッドは作成されない

  * `start()` はスレッドを**実行可能状態**にする命令 (実行状態にするわけではない)
  * 実行状態になったときに`run()`が呼ばれる
  * 終了したスレッドは再実行できない(IllegalThreadStateException)
  * `getPriority()`/`setPriority()`で優先度を設定できる (1[Min] → 10[Max])
  * ただし必ず優先順で実行される保証はない
  * Thread制御メソッド

    メソッド|概要
    :---|:---
    static void sleep(long millis)|このメソッドを呼び出したスレッドが指定時間休止する<br>休止後は**実行可能状態**に遷移する
    final void join()|実行中のスレッドの終了を待機する
    static void yield()|現在実行中のスレッドを一時休止して、他のスレッドに実行の機会を与える
    void interrupt()|休止中のスレッドに割り込みを入れる<br>割り込まれたスレッドはInterruptedExceptionを受け取る

* synchronizedキーワード
   * Singletonでおなじみ
     
    ```java
    // メソッドでロック
    synchronized void method1(int x) { ... }

    // オブジェクトでロック
    void method2(int y) {
      Object lock;
      synchronized(lock) { ... }
    }
    ```
    
  * staticメソッドでも使用可能
  * その場合はクラスに対してロックが取得される
  * abstractメソッドには記述できない
  * synchronizedメソッドをオーバーライドする場合は、明示的にsynchronizedキーワードをつけないと排他制御の対象にならない
    
* Objectクラスの同期制御
  
    メソッド|概要
    :---|:---
    final void wait()|ほかのスレッドは`notify()`/`notifyAll()`するまで現在のスレッドを待機させる
    final void wait(long timeout)|タイムアウト版
    final void notify()|このオブジェクトの待機中のスレッドを1つ再開する<br>再開対象は選べない
    final void notifyAll()|このオブジェクトの待機中のすべてのスレッドを再開する

   * synchronizedブロック以外で使用すると例外(IllegalMonitorStateException)

* 並列コレクション
  * Queue
 
    インタフェース/クラス|概要
   :---|:---
  BlockingQueue インタフェース|要素取り出しの際にキューを空にしないよう待機する
  SynchronousQueue クラス|基本的なブロッキングキュー
  LinkedBlockingQueue クラス|リンクノードに基づく
  ArrayBlockingQueue クラス|配列に基づく
  PriorityBlockingQueue クラス|ヒープに基づく優先順位を設定できる
  DelayQueue クラス|遅延時間経過後にのみ値を取得できる

  * Map

    インタフェース/クラス|概要
  :---|:---
  ConcurrentMap インタフェース|アトミックなメソッドを提供<br>`putIfAbsent()`、`remove()`、`replace()`
  ConcurrentHashMap クラス| ConcurrentMap実装クラス

  * ArrayList、Set

     インタフェース/クラス|概要
  :---|:---
  CopyOnWriteArrayList|配列をコピーしてスレッドセーフを実現するList
  CopyOnWriteArraySet|内部でCopyOnWriteArrayListを使用するSet


* Executorフレームワーク

  * スレッドの再利用やスケジューリングを簡単に行うためのフレームワーク
  
    インタフェース/クラス|概要
  :---|:---
  Executor インタフェース| Runnableタスクを実行する
  ExecutorService インタフェース|終了を管理するメソッド、進捗を追跡できるFutureを生成するメソッドの提供
  Future インタフェース|非同期計算の結果を返す<br>完了チェック、待機、結果の取得などのメソッドの提供
  Callable インタフェース|タスクを行うクラス<br>例外をスロー出来る
  Executors クラス| ファクトリ、Utilityメソッドの提供
  TreadPoolExecutor クラス|Java7から<br>プールされた複数のスレッドの1つを使用してタスクを実行する
  ScheduleｄThreadPoolExecutor クラス|Java7から<br>指定された遅延時間後、または定期的にタスクを実行する

    ```java
    ExecutorService ex = Executors.newSingleThreadExecutor();
    ex.execute(new MyThreadA()); // MyThreadAはRunnableを実装
    ```

* Fork/Joinフレームワーク
  * 重い計算を小さなタスクに分割して並行実行する
  
    インタフェース/クラス|概要
  :---|:---
  ForkJoinPool クラス|ExecutorServiceの実装クラス
  ForkJoinTask クラス|ForkJoinPool内で実行する抽象基底クラス
  RecursiveAction クラス|結果を返さないForkJoinTaskのサブクラス
  RecursiveTask クラス|結果を生成するForkJoinTaskのサブクラス

  * RecursiveAction/RecursiceTask をサブクラス化して利用
  
    ```java
    class Calc extends RecursiceTask<Integer> {
      final int _val;
      Calc(int val) {
        this._val = val;
      }
      protected Integer compute() {
        if (val <= 1) {
          return val;
        }
        Calc cal1 = new Calc(val - 1);
        cal1.fork(); // 処理実行
        Calc cal2 = new Calc(val - 2);
        return cal2.compute() + cal1.join(); // 完了を待機して結果取得
      }
    }

    // int result = new Calc().invoke();
    ```

次はJava8移行試験編でお会いしましょう。