[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 12521] Re: Java Concurrency In Practice 第 4 回議 事録



こんばんは遠藤です。

> newSingleThreadExecutorは、newFixedThreadPoolでサイズ1を指定した場合と
同じか?
> →違いそうである

newSingleThreadExecutorのAPIには、違いは以下のように説明されていました。

Unlike the otherwise equivalent newFixedThreadPool(1) the returned
executor is guaranteed not to be reconfigurable to use additional threads.

超訳すると、
  newFixedThreadPool(1)との違いは
  newSingleThreadExecutorの方は、
  reconfigurableではない
と言っています。

これだけだと何のことやらなので
Exectorsの実装を見てみました。

どちらもThreadPoolExecutorをnewしていますが
Singleの方は作ったExecutorを直接返すのではなく
DelegatedExecutorServiceでラップして返しています。

    public static ExecutorService newSingleThreadExecutor() {
        return new DelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,

内部クラス DelegatedExecutorService のコメントを見ると
     * A wrapper class that exposes only the ExecutorService methods
     * of an implementation.
と書いてあります。

ちょっと信じがたい気もしますが
結局のところ返されたExecutorがThreadPoolにダウンキャスト
可能か否かが違いのように見えます。
ThreadPoolExecutorにダウンキャストしさえすれば
スレッド数などは、確かにreconfigurable のようですし。

実際、サンプルとして

    public static void main(String[] args) {
        ExecutorService fixedOne =
            Executors.newFixedThreadPool(1);

        // Legal?
        ThreadPoolExecutor oneThreadPool =
            (ThreadPoolExecutor) fixedOne;

        ExecutorService single =
            Executors.newSingleThreadExecutor();
        // Illegal
        ThreadPoolExecutor singleThreadPool =
            (ThreadPoolExecutor) single;

    }

を実行してみると、

Exception in thread "main" java.lang.ClassCastException:
java.util.concurrent.Executors$DelegatedExecutorService
        at ThreadPoolOrNot.main(ThreadPoolOrNot.java:18)

singleをダウンキャストすると例外になります。

個人的には、どちらもダウンキャストできるかどうかは
保証しないという仕様で良いと思いますが。

では。




TAKAHASHI,Toru wrote:
> 「JavaConcurrencyInPracticeを読む会4回」
> 日時:10月21日 10:00-17:00
> 場所:中原市民館第3会議室
> 出席者(敬称略):門脇、村上、根本、岩永、村山、遠藤、岩室、吉本、小松、早川、大石、岡澤、高橋(智)、高橋(徹)
> 
> □読書会
> ○ 5.4 Blocking and interruptible methods
> 割り込まれたことを知るメソッドは2つある
>  interrupted :
>  isInterrupted:staticで、割り込み状態をクリアしてしまう
> 
> p.93 "cooperative"とはどう訳す
>   協調
>   割り込み
> 
> Restore the interrupted
>   interrupt() を呼ぶと、どこかでInterruptedExceptionが発生する
>   Propagateする方法と違って、interruptを記録してから処理を継続することもできる
> 
> IBM developerWorksの記事「Javaの理論と実践:割り込み例外の処理」2006.5.23
> 
> ○ 5.5 Synchronizers 
> 
> 5.5.1 Latches
> 
> List 5.11
> t.start()は非同期なので、すべてのスレッドがstartGate.await()を呼び出したあとに、startGate.countDown()が呼び出せる保証はない。
>   開始を一斉にしたいときにCountDownLatchではむかない(むしろBarrierがよい)のでは
> 
> 外側のtry-catchで例外が発生すると、endGate.countDown()が呼ばれないので、finally句は外側のtryにも必要では?
> そもそも2つのネストしたtryが必要なの?
> この例では、thread tがローカル変数で漏洩していないので、割り込みかける人がいないので問題ないのでは
> 
> 5.5.2 FutureTask
> 
> List.5.12
> getメソッドは、InterruptedException, ExecutionExceptionのチェック例外の他、CancellationExceptionの実行時例外をスローする
> 
> List 5.13
> 不思議なメソッド
> 
> 5.5.3 Semaphores
> 
> 
> 5.5.4 Barrier
> CyclicBarrierで、条件が成立したときにbarrier actionを呼び出すスレッドは、最後にawaitしたスレッドとなっている。
> awaitの戻り値のインデックスは、awaitに入った逆順(0が最後)。
> 
> シミュレーション例、3つ以上の惑星間の動きを計算する。2点間の引力しか算出できないため。
> 
> オートマトン
>   セルオートマトン
>     ライフゲーム
>       
> ○ 5.6 Building an efficient, scalable result cache 
> Memoizerの発音?
> Perlには標準でMemoizeパッケージがあり、キャッシュ等に使える
> 
> putIfAbsentは、Tigerから導入
> 
> List5.19 while文は、キャンセル時に処理を継続することを意図したもの
> FutureTaskでCancellationExceptionが発生するのは、FutureTaskのcancelを誰かが呼び出したあとでgetを呼び出した場合。このサンプルコードでは、cancelを呼び出せる人が存在しないので発生することはない。
> 
> ○ 6.1 Executing tasks in threads 
> graceful degradationの訳は?
> 
> 6.1.1 Executing tasks sequentially
> 次のacceptを行わないとリッスン・キューに溜る
> 宿題) リッスンキューが溢れたときはどうなるのか?
> 
> 注1)
> マルチスレッド対応なGUIはあるのか?
> 
> 6.1.2 Explicitly creating threads for tasks
> finalは外せないの? → コンパイルエラーとなる
> 
> 6.1.3 Disadvantages of unbounded thread creation
> 
> OSの設定で、スレッド数上限の規定あり
> (プロセスあたりのスレッド数)
> 
> Linux 2.4だと、スレッド数はID上限で8192に壁あり
> 
> 宿題)各自自分のマシンで最大スレッド数を調べてみよう
> 
> ○ 6.2 The Executor framework 
> 英語で朗読し、訳はなしに議論することで進める
> 読み手:大石さん、遠藤さん
> 
> Executorは、「登録」と「実行」を分離している
> 
> Executorは、生産者-消費者設計を実装するのに簡単に使える
> 
> exec.execute(task)で上限になるとどうなるのか? → 6.2.2
> 
> 6.2.2 Execution policies
> 
> newSingleThreadExecutorは、newFixedThreadPoolでサイズ1を指定した場合と同じか?
> →違いそうである
> 
> 6.2.4 Executor lifycycle
> ExecutorServiceはどうやって取得するのか?
> →newXXThreadの戻り値が実はExecutorServiceを実装している。受け取る型をExecutorからExecutorServiceへ変更すればよい。
> 
> shutdownNow()の戻り値で返却されるリストは
>   まだ実行されていないタスクのリスト
>   実行中のタスクは、(通常の実装では)Thread.interruptで割り込みする
> 
> 6.2.5 Delayed and periodic tasks
> Timer: システム時刻が変更(特に逆行)する場合問題が発生する。
>   NTPでも大きく時刻がずれると一気に変更することがある
> 
> ○ 6.3 Finding exploitable parallelism
> 6.3.1-6.3.3 
> 
> 6.3.4-6.3.8 
> 
> 6.3.4 
> パイプライン処理みたいなもの。どこかでボトルネックが生じる
> 
> 6.3.6
> completionService.take()は一定回数のforループではないといけないのか
> → takeはブロックメソッドなので、完了したCallableの数以上のtakeをすると、ずっとブロックしたままとなってしまう
> 
> リスト6.17
> quotesとtasksと2つのリストが一つのfor文のなかで入り乱れているが、必要なコーディングなのか?
>   f.get()が主処理
>   get()が失敗することがありえる
>     デフォルトの画像を表示したい、それを知っているのはtaskしかない
>   quoteリストとtaskリストは順番が一致しているのが前提
>   ExecutionExceptionに発生元のthisが入っていればいいじゃないか?
> 
> 
> 
> --
> TAKAHASHI,Toru
> torutk@xxxxxxxxxxxx
> 
> 


-- 
// Y. Endoh


import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class ThreadPoolOrNot{
    public static void main(String[] args) {
        ExecutorService fixedOne =
            Executors.newFixedThreadPool(1);

        // Legal?
        ThreadPoolExecutor oneThreadPool =
            (ThreadPoolExecutor) fixedOne;

        ExecutorService single =
            Executors.newSingleThreadExecutor();
        // Illegal
        ThreadPoolExecutor singleThreadPool =
            (ThreadPoolExecutor) single;

    }
}