SlideShare a Scribd company logo
1 of 18
Download to read offline
Effective Java 輪読会 
Item 71-73 
開発部陳映融2014/3/5
第10章並行性 
 項目66 共有された可変データへのアクセスを同期する 
 項目67 過剰な同期は避ける 
 項目68 スレッドよりエグゼキューターとタスクを選ぶ 
 項目69 wait とnotify よりコンカレンシーユーティリティを選ぶ 
 項目70 スレッド安全性を文書化する 
 項目71 遅延初期化を注意して使用する 
 項目72 スレッドスケジューラに依存しない 
 項目73 スレッドグループを避ける 
2
Item 71 
遅延初期化を注意して使用する
遅延初期化について 
 遅延初期化とは? 
4 
 フィールドの値が必要となるまで、フィールドの初期化を遅らせる行為 
 どこで使用する? 
 static フィールドとインスタンスフィールドの両方に適用可能 
 なんのための技法? 
 主に最適化のために使用 
 アクセスコストの増加を犠牲に 
 クラスの初期化コストやインスタンスの生成コストを減少させる 
 クラスとインスタンスの初期化において問題がある循環を断ち切るためにも 
 例: “Java Puzzlers”, Puzzle 51: What’s the Point?
最適化での使用に対する最高の助言 
 「項目55 注意して最適化する」を思い出して... 
 必要でなければするな 
5 
 フィールドがクラスの複数インスタンスの一部でだけアクセスされる 
 そしてフィールドの初期化にコストを要する場合は価値ある...かもしれない 
 実際のパフォーマンスを測定したうえ判断すべき 
 アクセスコストとクラス初期化コスト・インスタンス生成コストのトレードオフ 
 頻繁にアクセスされる場合は、かえってパフォーマンスを悪くする可能性も
複数スレッドでの遅延初期化 
 複数スレッドがフィールドを共有する場合、同期の形式が重要で、そうしな 
6 
いと深刻なバグとなることも(項目66) 
 殆どの場合は、遅延初期化より普通の初期化が望ましい 
// インスタンスフィールドの初期化: final 修飾子使用した普通の初期化 
private final FieldType field = computeFieldValue(); 
 初期化循環を断ち切るために遅延初期化を使用した場合 
 同期されたアクセッサーを使用 
// インスタンスフィールドの初期化: 同期されたアクセッサー内の遅延初期化 
private FieldType field; 
synchronized FieldType getField() { 
if (field == null) 
field = computeFieldValue(); 
return field; 
} 
 上記の2つのイデオムはフィールド宣言とアクセッサー宣言にstatic 修飾子を 
追加するだけでstatic フィールドに適用できる
複数スレッドでの遅延初期化 
 パフォーマンスのためstatic フィールドに遅延初期化を適用する場合 
7 
 遅延初期化(オンデマンド初期化)ホルダークラスイデオムを使用 
// static フィールドに対する遅延初期化ホルダークラスイデオム 
private static class FieldHolder { 
static final FieldType field = computeFieldValue(); 
} 
static FieldType getField() { // 同期が不要なのでアクセスコストが実質的に増えない! 
return FieldHolder.field; // 呼び出された時に初めてFieldHolder.field 初期化 
} 
 パフォーマンスのためインスタンスフィールドに遅延初期化を適用する場合 
 二重チェックイデオムを使用 
// インスタンスフィールドに対する遅延初期化のための二重チェックイデオム 
private volatile FieldType field; 
FieldType getField() { 
FieldType result = field; // result がfield が初期化済みの場合は一回しか読み込まれないことを保証 
if (result == null) { // 1回目検査(ロックなし) 
synchronized (this) { 
result = field; 
if (result == null) // 2回目検査(ロックあり) 
field = result = computeFieldValue(); 
} 
} 
return result; 
}
複数スレッドでの遅延初期化 
 複数回の初期化を許容できるインスタンスフィールドの場合 
8 
 二重チェックイデオムの変形:単一チェックイデオム 
// 単一チェックイデオム 
private volatile FieldType field; 
FieldType getField() { 
FieldType result = field; 
if (result == null) // 2回目のチェックがなくなり同期しなくなったため、複数回初期化されるかも 
field = result = computeFieldValue(); 
return result; 
 すべてのスレッドでフィールド値(long/double以外の基本型)が再計算 
されても気にしない場合 
 二重チェックイデオムの変形:きわどい単一チェックイデオム 
 インスタンスフィールドのvolatile 修飾子を取り除く 
 long/double がダメな理由は、変数のwrite 処理はアトミックでないため[JLS17.7] 
 非標準技法であって普段用ではない 
 が、String のハッシュコードをキャッシュするため使用されている 
}
まとめ 
 殆どのフィールドは普通に初期化するべき(遅延なし) 
 遅延初期化を使用しなければならない場合は適切な技法を使用 
9 
 初期化循環を断ち切るため 
 同期されたアクセッサー 
 パフォーマンス目標を達成するため:staticフィールド 
 遅延初期化ホルダークラスイデオム 
 パフォーマンス目標を達成するため:インスタンスフィールド 
 二重チェックイデオム(一回のみ初期化) 
 単一チェックイデオム(複数回初期化許容)
Item 72 
スレッドスケジューラに依存しない
スレッドスケジューラとの付き合い方 
 スレッドスケジューラの仕事 
 実行可能な複数スレッドに対して、それぞれのスレッドの実行時間を決める 
 時間の決め方はOS やJVM 実装によって、ポリシーが異なる可能性がある 
⇒ プログラムの正しさやパフォーマンスがスレッドスケジューラに依存すると移植 
できなくなる 
 頑強で応答性のよい移植可能なプログラムを書くための最善策 
 実行可能なスレッドの数がプロセッサの数より、大きくなり過ぎないように保証 
11 
⇒ 選択肢を狭めることで、スレッドスケジューラの動きの差異を抑える
実行可能なスレッドの数を少なく保つ技法 
 個々のスレッドに何らか有益な処理を行わせてから、そこからさらなる処 
理を待たせる 
 有益な処理を行っていない場合は動作すべきではない 
12 
 ビジーウェイトは使用しないように 
⇒ 他のスレッドの有益な処理の量を減らせてしまう 
 エグゼキューターフレームワークに関して言うと 
 スレッドプールを適切大きさにする 
 タスクを適度に小さくする 
 他のタスクから独立させる 
 タスクはあまり小さくするべきではない 
⇒ ディスパッチするオーバーヘッドによりパフォーマンスが低下する
Thread.yield の使用について 
 Thread.yield メソッド 
 現在使用中のプロセッサを譲ってもいい、という意思表示 
 スレッドスケジューラへのヒントだけなので、無視されても文句言えない 
13 
⇒ テスト可能なセマンティックスを持っていない 
 実行時間が得られなくて殆ど動かないプログラムに直面した場合 
 Thread.yield の呼び出しを入れてプログラムを「修理」する? 
 使用中のJVM 実装では動くかも知れないが 
 他のJVM 実装ではどうなるかわからない 
 アプリケーションを再構築して、並行して実行可能スレッド数を減らすべき 
 並行性検査のために使用しないこと 
 代わりにThread.sleep(1) を使用すること 
 すぐに戻ってくる可能性のあるThread.sleep(0) は使わないように
まとめ 
 アプリケーションの正しさに関してスレッドスケジューラに依存してはだめ 
 依存性のあるアプリケーションは頑健でもない、移植可能でもない 
 スケジューラに対するヒントとなる機構のThread.yield やスレッドの 
優先順位に依存してもだめ 
 動作しているプログラムの品質を改善するのにスレッドの優先順位を控えめに 
14 
使用してもよい 
 殆ど動作しないプログラムの「修理」に使用するべきではない
Item 73 
スレッドグループを避ける
スレッドグループって? 
 スレッドシステムが提供している基本的な抽象概念 
 スレッドの集合を表す 
 (以下省略) 
 セキュリティ目的のためにアプレットを隔離する仕組みとして考案された 
 役割を果たすことなかった 
 重要性も小さくなった(セキュリティモデルの標準書が言及しないほど) 
16
スレッドグループが使用されない理由 
 たいして機能を提供していない 
 Thread の基本操作を一度に多くのスレッドに適用することを可能にする 
 いくつか推奨されない操作や、めったに使わない操作... 
 ThreadGroup API はスレッド安全性の観点から貧弱 
 enumerate:配列に入りきらないスレッドグループはそのまま無視される 
 activeCount:アクティブなスレッドの数の「推定値」を返す 
 activeGroupCount:アクティブなスレッドグループの数の「推定値」を返す 
 ThreadGroup API だけが提供している機能はもう存在しない 
 スレッドがスローした例外がキャッチされない場合の制御手段 
17 
 リリース1.5 より前はThreadGroup.uncaughtException だけ 
 リリース1.5 以降はThread.setUncaughtExceptionHandler
まとめ 
 スレッドグループは有用な機能を提供していないし、提供している機能の 
殆どに欠陥がある 
 スレッドグループを成功しなかった実験とみなして、その存在を無視しても 
よい 
 スレッドを論理的なグループを扱うクラスを設計するなら、おそらく、スレッ 
ドプールエグゼキューターを使用すべき 
 要するに、スレッドグループをなかったことにしよう 
18

More Related Content

What's hot

Reactive Extensions v2.0
Reactive Extensions v2.0Reactive Extensions v2.0
Reactive Extensions v2.0Yoshifumi Kawai
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsYoshifumi Kawai
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Yoshifumi Kawai
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するshigeki_ohtsu
 
ret2dl resolve
ret2dl resolveret2dl resolve
ret2dl resolvesounakano
 
effective modern c++ chapeter36
effective modern c++ chapeter36effective modern c++ chapeter36
effective modern c++ chapeter36Tatsuki SHIMIZU
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用MITSUNARI Shigeo
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチKazuki Onishi
 
エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半Tetsuya Morimoto
 
nakameguro_feature.cpp vol.8
nakameguro_feature.cpp vol.8nakameguro_feature.cpp vol.8
nakameguro_feature.cpp vol.8yohhoy
 
Preludeのprecompile
PreludeのprecompilePreludeのprecompile
PreludeのprecompileGlass_saga
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うKenji Kazumura
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALegtra
 
Return Oriented Programming
Return Oriented ProgrammingReturn Oriented Programming
Return Oriented Programmingsounakano
 
PHPとシグナル、その裏側
PHPとシグナル、その裏側PHPとシグナル、その裏側
PHPとシグナル、その裏側do_aki
 

What's hot (20)

Reactive Extensions v2.0
Reactive Extensions v2.0Reactive Extensions v2.0
Reactive Extensions v2.0
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
 
ret2dl resolve
ret2dl resolveret2dl resolve
ret2dl resolve
 
ret2libc
ret2libcret2libc
ret2libc
 
effective modern c++ chapeter36
effective modern c++ chapeter36effective modern c++ chapeter36
effective modern c++ chapeter36
 
Sharing Deep Dive
Sharing Deep DiveSharing Deep Dive
Sharing Deep Dive
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用
 
Effective modern-c++#9
Effective modern-c++#9Effective modern-c++#9
Effective modern-c++#9
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチ
 
エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半
 
nakameguro_feature.cpp vol.8
nakameguro_feature.cpp vol.8nakameguro_feature.cpp vol.8
nakameguro_feature.cpp vol.8
 
Preludeのprecompile
PreludeのprecompilePreludeのprecompile
Preludeのprecompile
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使う
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
 
Return Oriented Programming
Return Oriented ProgrammingReturn Oriented Programming
Return Oriented Programming
 
PHPとシグナル、その裏側
PHPとシグナル、その裏側PHPとシグナル、その裏側
PHPとシグナル、その裏側
 
Stack pivot
Stack pivotStack pivot
Stack pivot
 

Viewers also liked

JavaScript 勉強会 ― 変数・演算子・文
JavaScript 勉強会 ― 変数・演算子・文JavaScript 勉強会 ― 変数・演算子・文
JavaScript 勉強会 ― 変数・演算子・文Appresso Engineering Team
 
Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44Appresso Engineering Team
 
マルチスレッド デザインパターン ― Single Threaded Execution
マルチスレッド デザインパターン ― Single Threaded Executionマルチスレッド デザインパターン ― Single Threaded Execution
マルチスレッド デザインパターン ― Single Threaded ExecutionAppresso Engineering Team
 
[AWSマイスターシリーズ] AWS CLI / AWS Tools for Windows PowerShell
[AWSマイスターシリーズ] AWS CLI / AWS Tools for Windows PowerShell[AWSマイスターシリーズ] AWS CLI / AWS Tools for Windows PowerShell
[AWSマイスターシリーズ] AWS CLI / AWS Tools for Windows PowerShellAmazon Web Services Japan
 

Viewers also liked (15)

Effective Java 輪読会 項目69-70追加
Effective Java 輪読会 項目69-70追加Effective Java 輪読会 項目69-70追加
Effective Java 輪読会 項目69-70追加
 
Effective Java 輪読会 項目69-70
Effective Java 輪読会 項目69-70Effective Java 輪読会 項目69-70
Effective Java 輪読会 項目69-70
 
Effective Java 輪読会 項目63-65
Effective Java 輪読会 項目63-65Effective Java 輪読会 項目63-65
Effective Java 輪読会 項目63-65
 
JavaScript 勉強会 ― 変数・演算子・文
JavaScript 勉強会 ― 変数・演算子・文JavaScript 勉強会 ― 変数・演算子・文
JavaScript 勉強会 ― 変数・演算子・文
 
Effective Java 輪読会 項目53-56
Effective Java 輪読会 項目53-56Effective Java 輪読会 項目53-56
Effective Java 輪読会 項目53-56
 
JavaScript 勉強会 ― 型と値
JavaScript 勉強会 ― 型と値JavaScript 勉強会 ― 型と値
JavaScript 勉強会 ― 型と値
 
Effective Java 輪読会 項目74-75
Effective Java 輪読会 項目74-75Effective Java 輪読会 項目74-75
Effective Java 輪読会 項目74-75
 
Effective Java 輪読会 項目60-62
Effective Java 輪読会 項目60-62Effective Java 輪読会 項目60-62
Effective Java 輪読会 項目60-62
 
Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44
 
Effective Java 輪読会 項目45-48
Effective Java 輪読会 項目45-48Effective Java 輪読会 項目45-48
Effective Java 輪読会 項目45-48
 
Effective Java 輪読会 項目77-78
Effective Java 輪読会 項目77-78Effective Java 輪読会 項目77-78
Effective Java 輪読会 項目77-78
 
Effective Java 輪読会 項目49-52
Effective Java 輪読会 項目49-52Effective Java 輪読会 項目49-52
Effective Java 輪読会 項目49-52
 
マルチスレッド デザインパターン ― Single Threaded Execution
マルチスレッド デザインパターン ― Single Threaded Executionマルチスレッド デザインパターン ― Single Threaded Execution
マルチスレッド デザインパターン ― Single Threaded Execution
 
20150302 java8 第一回_ラムダ式(1)
20150302 java8 第一回_ラムダ式(1)20150302 java8 第一回_ラムダ式(1)
20150302 java8 第一回_ラムダ式(1)
 
[AWSマイスターシリーズ] AWS CLI / AWS Tools for Windows PowerShell
[AWSマイスターシリーズ] AWS CLI / AWS Tools for Windows PowerShell[AWSマイスターシリーズ] AWS CLI / AWS Tools for Windows PowerShell
[AWSマイスターシリーズ] AWS CLI / AWS Tools for Windows PowerShell
 

Similar to Effective Java 輪読会 項目71-73

使い捨て python コードの書き方
使い捨て python コードの書き方使い捨て python コードの書き方
使い捨て python コードの書き方Sho Shimauchi
 
【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門 【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門 sandai
 
ビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテストビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテストTsutomu Chikuba
 
C#coding guideline その2_20130325
C#coding guideline その2_20130325C#coding guideline その2_20130325
C#coding guideline その2_20130325Yoshihisa Ozaki
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageTaku Miyakawa
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~normalian
 

Similar to Effective Java 輪読会 項目71-73 (7)

使い捨て python コードの書き方
使い捨て python コードの書き方使い捨て python コードの書き方
使い捨て python コードの書き方
 
20141129-dotNet2015
20141129-dotNet201520141129-dotNet2015
20141129-dotNet2015
 
【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門 【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門
 
ビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテストビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテスト
 
C#coding guideline その2_20130325
C#coding guideline その2_20130325C#coding guideline その2_20130325
C#coding guideline その2_20130325
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 

More from Appresso Engineering Team

Effective Java 輪読会 第7章 項目41-42
Effective Java 輪読会 第7章 項目41-42Effective Java 輪読会 第7章 項目41-42
Effective Java 輪読会 第7章 項目41-42Appresso Engineering Team
 
Effective Java 輪読会 第7章 項目38-40
Effective Java 輪読会 第7章 項目38-40Effective Java 輪読会 第7章 項目38-40
Effective Java 輪読会 第7章 項目38-40Appresso Engineering Team
 
Effective Java 輪読会 第6章 項目35-37
Effective Java 輪読会 第6章 項目35-37Effective Java 輪読会 第6章 項目35-37
Effective Java 輪読会 第6章 項目35-37Appresso Engineering Team
 
Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34Appresso Engineering Team
 
Effective java 輪読会 第6章 項目30-31
Effective java 輪読会 第6章 項目30-31Effective java 輪読会 第6章 項目30-31
Effective java 輪読会 第6章 項目30-31Appresso Engineering Team
 
Effective java 輪読会 第5章 項目26-29
Effective java 輪読会 第5章 項目26-29Effective java 輪読会 第5章 項目26-29
Effective java 輪読会 第5章 項目26-29Appresso Engineering Team
 
Effective java 輪読会 第5章 項目23-25
Effective java 輪読会 第5章 項目23-25Effective java 輪読会 第5章 項目23-25
Effective java 輪読会 第5章 項目23-25Appresso Engineering Team
 
Effective java 輪読会 第4章 項目18-22
Effective java 輪読会 第4章 項目18-22Effective java 輪読会 第4章 項目18-22
Effective java 輪読会 第4章 項目18-22Appresso Engineering Team
 
Effective Java 輪読会 第4章 項目13-17
Effective Java 輪読会 第4章 項目13-17Effective Java 輪読会 第4章 項目13-17
Effective Java 輪読会 第4章 項目13-17Appresso Engineering Team
 
Effective java 輪読会 第3章 項目11, 12
Effective java 輪読会 第3章 項目11, 12Effective java 輪読会 第3章 項目11, 12
Effective java 輪読会 第3章 項目11, 12Appresso Engineering Team
 
Effective java 輪読会 第3章 項目8,9,10
Effective java 輪読会 第3章 項目8,9,10Effective java 輪読会 第3章 項目8,9,10
Effective java 輪読会 第3章 項目8,9,10Appresso Engineering Team
 
Effective java 輪読会 第2章 項目5,6,7
Effective java 輪読会 第2章 項目5,6,7Effective java 輪読会 第2章 項目5,6,7
Effective java 輪読会 第2章 項目5,6,7Appresso Engineering Team
 
Effective java 輪読会 第2章 項目1,2,3,4
Effective java 輪読会 第2章 項目1,2,3,4Effective java 輪読会 第2章 項目1,2,3,4
Effective java 輪読会 第2章 項目1,2,3,4Appresso Engineering Team
 

More from Appresso Engineering Team (15)

Java Day Tokyo 2014 まとめ (chen)
Java Day Tokyo 2014 まとめ (chen)Java Day Tokyo 2014 まとめ (chen)
Java Day Tokyo 2014 まとめ (chen)
 
Effective java 輪読会 項目57-59
Effective java 輪読会 項目57-59Effective java 輪読会 項目57-59
Effective java 輪読会 項目57-59
 
Effective Java 輪読会 第7章 項目41-42
Effective Java 輪読会 第7章 項目41-42Effective Java 輪読会 第7章 項目41-42
Effective Java 輪読会 第7章 項目41-42
 
Effective Java 輪読会 第7章 項目38-40
Effective Java 輪読会 第7章 項目38-40Effective Java 輪読会 第7章 項目38-40
Effective Java 輪読会 第7章 項目38-40
 
Effective Java 輪読会 第6章 項目35-37
Effective Java 輪読会 第6章 項目35-37Effective Java 輪読会 第6章 項目35-37
Effective Java 輪読会 第6章 項目35-37
 
Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34
 
Effective java 輪読会 第6章 項目30-31
Effective java 輪読会 第6章 項目30-31Effective java 輪読会 第6章 項目30-31
Effective java 輪読会 第6章 項目30-31
 
Effective java 輪読会 第5章 項目26-29
Effective java 輪読会 第5章 項目26-29Effective java 輪読会 第5章 項目26-29
Effective java 輪読会 第5章 項目26-29
 
Effective java 輪読会 第5章 項目23-25
Effective java 輪読会 第5章 項目23-25Effective java 輪読会 第5章 項目23-25
Effective java 輪読会 第5章 項目23-25
 
Effective java 輪読会 第4章 項目18-22
Effective java 輪読会 第4章 項目18-22Effective java 輪読会 第4章 項目18-22
Effective java 輪読会 第4章 項目18-22
 
Effective Java 輪読会 第4章 項目13-17
Effective Java 輪読会 第4章 項目13-17Effective Java 輪読会 第4章 項目13-17
Effective Java 輪読会 第4章 項目13-17
 
Effective java 輪読会 第3章 項目11, 12
Effective java 輪読会 第3章 項目11, 12Effective java 輪読会 第3章 項目11, 12
Effective java 輪読会 第3章 項目11, 12
 
Effective java 輪読会 第3章 項目8,9,10
Effective java 輪読会 第3章 項目8,9,10Effective java 輪読会 第3章 項目8,9,10
Effective java 輪読会 第3章 項目8,9,10
 
Effective java 輪読会 第2章 項目5,6,7
Effective java 輪読会 第2章 項目5,6,7Effective java 輪読会 第2章 項目5,6,7
Effective java 輪読会 第2章 項目5,6,7
 
Effective java 輪読会 第2章 項目1,2,3,4
Effective java 輪読会 第2章 項目1,2,3,4Effective java 輪読会 第2章 項目1,2,3,4
Effective java 輪読会 第2章 項目1,2,3,4
 

Recently uploaded

2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~arts yokohama
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法ssuser370dd7
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見Shumpei Kishi
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-LoopへTetsuya Nihonmatsu
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor arts yokohama
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)ssuser539845
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfMatsushita Laboratory
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdfAyachika Kitazaki
 

Recently uploaded (11)

2024 03 CTEA
2024 03 CTEA2024 03 CTEA
2024 03 CTEA
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
 
2024 04 minnanoito
2024 04 minnanoito2024 04 minnanoito
2024 04 minnanoito
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
 
What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf
 

Effective Java 輪読会 項目71-73

  • 1. Effective Java 輪読会 Item 71-73 開発部陳映融2014/3/5
  • 2. 第10章並行性  項目66 共有された可変データへのアクセスを同期する  項目67 過剰な同期は避ける  項目68 スレッドよりエグゼキューターとタスクを選ぶ  項目69 wait とnotify よりコンカレンシーユーティリティを選ぶ  項目70 スレッド安全性を文書化する  項目71 遅延初期化を注意して使用する  項目72 スレッドスケジューラに依存しない  項目73 スレッドグループを避ける 2
  • 4. 遅延初期化について  遅延初期化とは? 4  フィールドの値が必要となるまで、フィールドの初期化を遅らせる行為  どこで使用する?  static フィールドとインスタンスフィールドの両方に適用可能  なんのための技法?  主に最適化のために使用  アクセスコストの増加を犠牲に  クラスの初期化コストやインスタンスの生成コストを減少させる  クラスとインスタンスの初期化において問題がある循環を断ち切るためにも  例: “Java Puzzlers”, Puzzle 51: What’s the Point?
  • 5. 最適化での使用に対する最高の助言  「項目55 注意して最適化する」を思い出して...  必要でなければするな 5  フィールドがクラスの複数インスタンスの一部でだけアクセスされる  そしてフィールドの初期化にコストを要する場合は価値ある...かもしれない  実際のパフォーマンスを測定したうえ判断すべき  アクセスコストとクラス初期化コスト・インスタンス生成コストのトレードオフ  頻繁にアクセスされる場合は、かえってパフォーマンスを悪くする可能性も
  • 6. 複数スレッドでの遅延初期化  複数スレッドがフィールドを共有する場合、同期の形式が重要で、そうしな 6 いと深刻なバグとなることも(項目66)  殆どの場合は、遅延初期化より普通の初期化が望ましい // インスタンスフィールドの初期化: final 修飾子使用した普通の初期化 private final FieldType field = computeFieldValue();  初期化循環を断ち切るために遅延初期化を使用した場合  同期されたアクセッサーを使用 // インスタンスフィールドの初期化: 同期されたアクセッサー内の遅延初期化 private FieldType field; synchronized FieldType getField() { if (field == null) field = computeFieldValue(); return field; }  上記の2つのイデオムはフィールド宣言とアクセッサー宣言にstatic 修飾子を 追加するだけでstatic フィールドに適用できる
  • 7. 複数スレッドでの遅延初期化  パフォーマンスのためstatic フィールドに遅延初期化を適用する場合 7  遅延初期化(オンデマンド初期化)ホルダークラスイデオムを使用 // static フィールドに対する遅延初期化ホルダークラスイデオム private static class FieldHolder { static final FieldType field = computeFieldValue(); } static FieldType getField() { // 同期が不要なのでアクセスコストが実質的に増えない! return FieldHolder.field; // 呼び出された時に初めてFieldHolder.field 初期化 }  パフォーマンスのためインスタンスフィールドに遅延初期化を適用する場合  二重チェックイデオムを使用 // インスタンスフィールドに対する遅延初期化のための二重チェックイデオム private volatile FieldType field; FieldType getField() { FieldType result = field; // result がfield が初期化済みの場合は一回しか読み込まれないことを保証 if (result == null) { // 1回目検査(ロックなし) synchronized (this) { result = field; if (result == null) // 2回目検査(ロックあり) field = result = computeFieldValue(); } } return result; }
  • 8. 複数スレッドでの遅延初期化  複数回の初期化を許容できるインスタンスフィールドの場合 8  二重チェックイデオムの変形:単一チェックイデオム // 単一チェックイデオム private volatile FieldType field; FieldType getField() { FieldType result = field; if (result == null) // 2回目のチェックがなくなり同期しなくなったため、複数回初期化されるかも field = result = computeFieldValue(); return result;  すべてのスレッドでフィールド値(long/double以外の基本型)が再計算 されても気にしない場合  二重チェックイデオムの変形:きわどい単一チェックイデオム  インスタンスフィールドのvolatile 修飾子を取り除く  long/double がダメな理由は、変数のwrite 処理はアトミックでないため[JLS17.7]  非標準技法であって普段用ではない  が、String のハッシュコードをキャッシュするため使用されている }
  • 9. まとめ  殆どのフィールドは普通に初期化するべき(遅延なし)  遅延初期化を使用しなければならない場合は適切な技法を使用 9  初期化循環を断ち切るため  同期されたアクセッサー  パフォーマンス目標を達成するため:staticフィールド  遅延初期化ホルダークラスイデオム  パフォーマンス目標を達成するため:インスタンスフィールド  二重チェックイデオム(一回のみ初期化)  単一チェックイデオム(複数回初期化許容)
  • 11. スレッドスケジューラとの付き合い方  スレッドスケジューラの仕事  実行可能な複数スレッドに対して、それぞれのスレッドの実行時間を決める  時間の決め方はOS やJVM 実装によって、ポリシーが異なる可能性がある ⇒ プログラムの正しさやパフォーマンスがスレッドスケジューラに依存すると移植 できなくなる  頑強で応答性のよい移植可能なプログラムを書くための最善策  実行可能なスレッドの数がプロセッサの数より、大きくなり過ぎないように保証 11 ⇒ 選択肢を狭めることで、スレッドスケジューラの動きの差異を抑える
  • 12. 実行可能なスレッドの数を少なく保つ技法  個々のスレッドに何らか有益な処理を行わせてから、そこからさらなる処 理を待たせる  有益な処理を行っていない場合は動作すべきではない 12  ビジーウェイトは使用しないように ⇒ 他のスレッドの有益な処理の量を減らせてしまう  エグゼキューターフレームワークに関して言うと  スレッドプールを適切大きさにする  タスクを適度に小さくする  他のタスクから独立させる  タスクはあまり小さくするべきではない ⇒ ディスパッチするオーバーヘッドによりパフォーマンスが低下する
  • 13. Thread.yield の使用について  Thread.yield メソッド  現在使用中のプロセッサを譲ってもいい、という意思表示  スレッドスケジューラへのヒントだけなので、無視されても文句言えない 13 ⇒ テスト可能なセマンティックスを持っていない  実行時間が得られなくて殆ど動かないプログラムに直面した場合  Thread.yield の呼び出しを入れてプログラムを「修理」する?  使用中のJVM 実装では動くかも知れないが  他のJVM 実装ではどうなるかわからない  アプリケーションを再構築して、並行して実行可能スレッド数を減らすべき  並行性検査のために使用しないこと  代わりにThread.sleep(1) を使用すること  すぐに戻ってくる可能性のあるThread.sleep(0) は使わないように
  • 14. まとめ  アプリケーションの正しさに関してスレッドスケジューラに依存してはだめ  依存性のあるアプリケーションは頑健でもない、移植可能でもない  スケジューラに対するヒントとなる機構のThread.yield やスレッドの 優先順位に依存してもだめ  動作しているプログラムの品質を改善するのにスレッドの優先順位を控えめに 14 使用してもよい  殆ど動作しないプログラムの「修理」に使用するべきではない
  • 16. スレッドグループって?  スレッドシステムが提供している基本的な抽象概念  スレッドの集合を表す  (以下省略)  セキュリティ目的のためにアプレットを隔離する仕組みとして考案された  役割を果たすことなかった  重要性も小さくなった(セキュリティモデルの標準書が言及しないほど) 16
  • 17. スレッドグループが使用されない理由  たいして機能を提供していない  Thread の基本操作を一度に多くのスレッドに適用することを可能にする  いくつか推奨されない操作や、めったに使わない操作...  ThreadGroup API はスレッド安全性の観点から貧弱  enumerate:配列に入りきらないスレッドグループはそのまま無視される  activeCount:アクティブなスレッドの数の「推定値」を返す  activeGroupCount:アクティブなスレッドグループの数の「推定値」を返す  ThreadGroup API だけが提供している機能はもう存在しない  スレッドがスローした例外がキャッチされない場合の制御手段 17  リリース1.5 より前はThreadGroup.uncaughtException だけ  リリース1.5 以降はThread.setUncaughtExceptionHandler
  • 18. まとめ  スレッドグループは有用な機能を提供していないし、提供している機能の 殆どに欠陥がある  スレッドグループを成功しなかった実験とみなして、その存在を無視しても よい  スレッドを論理的なグループを扱うクラスを設計するなら、おそらく、スレッ ドプールエグゼキューターを使用すべき  要するに、スレッドグループをなかったことにしよう 18