SlideShare una empresa de Scribd logo
1 de 33
Descargar para leer sin conexión
Effective Java 輪読会第8回 
(項目66~68) 
2014/3/5 
開発部野口
項目66 
共有された可変データへのアクセスを同期す 
る
synchronized 
 以下の2 つを保証する 
 スレッドが、不整合な状態のオブジェクトを見な 
いこと 
 スレッドから、同じロックで保護されていた以前 
のすべての変更の結果が見えること
アトミックな型 
 long 型とdouble 型以外の変数の読み書きがア 
トミックであることは、言語仕様によって保 
証されている 
 では、パフォーマンスのため、アトミックなデー 
タへの読み書きでは同期を避けるべき? 
 そうではない
メモリモデル 
 言語仕様では、フィールドを読み出すときに 
スレッドがランダムな値を読み出さないこと 
を保証している 
 が、1 つのスレッドが書き込んだ値が他のス 
レッドからも見えることは保証していない 
 ので、アトミックなデータに対しても同期は 
有用
不完全な同期の例 
public class StopThread { 
private static boolean stopRequested; 
public static void main(String[] args) throws InterruptedException { 
Thread backgroundThread = new Thread(new Runnable() { public void 
run() { 
int i = 0; 
while (!stopRequested) 
i++; 
}}); 
backgroundThread.start(); 
TimeUnit.SECONDS.sleep(1); 
stopRequested = true; // この変更がbackgroundThread には伝わらな 
い! 
// ので、プログラムが終了しない(活性エラー) 
}}
巻き上げ 
 HotSpot Server VM は、以下のような変更を行う(この 
変更は許容されている) 
↓ 
while (!stopRequested) 
i++; 
if (!stopRequested) 
while (true) // !!! 
i++;
不完全な同期の修正案 
public class StopThread { 
private static boolean stopRequested; 
public static synchronized void requestStop() { 
stopRequested = true; 
} 
public static synchronized boolean stopRequested() { 
return stopRequested; 
} 
public static void main(String[] args) throws InterruptedException { 
Thread backgroundThread = new Thread(new Runnable() { public void run() { 
int i = 0; 
while (!stopRequested()) i++; 
}}); 
backgroundThread.start(); 
TimeUnit.SECONDS.sleep(1); 
requestStop(); // 変更がbackgroundThread にも反映される 
// ので、プログラムは1 秒で終了する 
}}
修正案の注意点 
 読み込み操作(stopRequested)と書き込み操 
作(requestStop)の両方が同期されている必 
要がある
volatile による修正案 
public class StopThread { 
private static volatile boolean stopRequested; 
public static void main(String[] args) throws InterruptedException { 
Thread backgroundThread = new Thread(new Runnable() { 
public void run() { 
int i = 0; 
while (!stopRequested) 
i++; 
} 
}); 
backgroundThread.start(); 
TimeUnit.SECONDS.sleep(1); 
stopRequested = true; // 反映される 
}
volatile の失敗例 
// 不完全- 同期が必要! 
private static volatile int nextSerialNumber = 0; 
public static int generateSerialNumber() { 
return nextSerialNumber++; // この操作はアトミックではない! 
// ので、タイミング次第では、複数のスレッドで 
// 同じシリアルナンバーを得てしまう(安全性エ 
ラー) 
}
AtomicLong 
public static synchronized long generateSerialNumber() { 
if (nextSerialNumber == Long.MAX_VALUE) 
throw new なんとかException(); 
return nextSerialNumber++; 
↑同等!(かつ、後者の方が速い可能性が高い)↓ 
} 
private static final AtomicLong nextSerialNum = new AtomicLong(); 
public static long generateSerialNumber() { 
return nextSerialNum.getAndIncrement(); 
}
可変データを共有しない 
 最善! 
 その際は、文書化しよう(方針が維持される 
ように) 
 フレームワークやライブラリを深く理解しよ 
う(内部でスレッドが用いられているかもし 
れない)
事実上不変 
 「少しの間スレッドがデータオブジェクトを 
変更してから、オブジェクト参照を共有する 
処理だけを同期する」 
 「オブジェクトが再び変更されない限り、他のス 
レッドはさらに同期することなくオブジェクトを 
読み出すことができる」 
// (”Java Concurrency in Practice” より引用) 
public Map<String, Date> lastLogin = 
Collections.synchronizedMap(new HashMap<String, Date>());
安全な公開 
 フィールドをstatic にして、クラス初期化に 
よろしくお願いする 
 フィールドをvolatile にする 
 フィールドをfinal にする 
 フィールドをロックで保護する 
 コンカレントコレクションを用いる
まとめ 
 複数のスレッドが可変データを共有する場合、そ 
のデータを読み書きするスレッドは同期を行う 
 同期なしでは、あるスレッドの変更が他のスレッドか 
ら見えることは保証されない 
 同期しないことへのペナルティ:活性エラーと安 
全性エラー 
 デバッグ困難! 
 タイミング依存、JVM 依存 
 スレッド間通信だけが必要な場合は、volatile も 
ある 
 ただし、正しく使用するのは難しい 
 詳しくは『Java Concurrency in Practice』を読も 
う(邦訳もあるよ)
項目67 過剰な同期は避ける
同期されたメソッドやブロック内 
で、制御をクライアントに譲らな 
い 
 オーバーライドされるように設計されている 
メソッドや関数オブジェクトを、同期された 
領域内で呼び出さない 
 <異質>なメソッドだから 
 メソッドが何をするかわからないため、例外、デッド 
ロック、データ破壊の可能性がある
異質なメソッド呼び出し 
(例外編) 
 ObservableSet(pp.256-257)と、 
SetObserver(pp.257) 
 SetObserver#added で 
ObservableSet#removeObserver を呼び出すと、 
ConcurrentModificationException がスローされ 
る!(pp.257-258) 
 リストをイテレート中に、そのリストから要素を削除 
しようとしているから
異質なメソッド呼び出し 
(デッドロック編) 
 再びObservableSet(pp.256-257)と、 
SetObserver(pp.257) 
 SetObserver#added で、ExecutorService 経由で 
ObservableSet#removeObserver を呼び出すと、 
デッドロックが発生する!(pp.258) 
 ObservableSet.observers のロックは、既にメインス 
レッドによって獲得されているから
異質なメソッド呼び出し 
(地獄編) 
 もし、 
1. 同期された領域により保護されている不変式が一時 
的に不正になっている間に、 
2. 同期された領域内から異質なメソッドを呼び出した 
ら、 
3. その異質なメソッドは首尾よくロックを獲得し(再 
帰的ロック)、 
4. オブジェクトの内部状態をこっそり不正にしてしま 
う!(かもしれない) 
 ロックが用をなしていない 
 再帰的ロックは、活性エラーを安全性エラーに変える 
可能性がある
異質なメソッド呼び出しの回避 
(オープンコール) 
private void notifyElementAdded(E element) { 
List<SetObserver<E>> snapshot = null; 
synchronized(observers) { 
snapshot = new ArrayList<SetObserver<E>>(observers); 
} 
for (SetObserver<E> observer : snapshot) 
observer.added(this, element); 
} 
 SetObserver#added の処理時間が長い場合、並行性 
を増大させるメリットも期待できる
異質なメソッド呼び出しの回避 
(CopyOnWriteArrayList) 
private final List<SetObserver<E>> observers = 
new CopyOnWriteArrayList<SetObserver<E>>(); 
public void addObserver(SetObserver<E> observer) { 
observers.add(observer); 
} 
public void notifyElementAdded(E element) { 
observer.added(this, element); 
} 
private void addObserver(SetObserver<E> observer) { 
for (SetObserver<E> observer : observers) 
observers.add(observer); 
}
同期のコスト 
 ロックに費やされるCPU 時間 
 よりも、並行処理を行う機会損失 
 および、すべてのコアがメモリの一貫した 
ビューを持つことを保証する必要性から生じ 
る遅延
内部同期と外部同期 
 クラスが並行して使用されるのであれば、可変クラス 
をスレッドセーフにすべき 
 static フィールドへのアクセスは、必ず内部同期が必 
要 
 関係のないクライアント同士が、同じルールで同期できる 
とは限らないから 
 StringBuffer とStringBuilder 
 StringBuffer は、ほとんどの場合に単一スレッドから使用 
されるのに、内部的に同期を行っている 
 リリース1.5 で、同期されていないStringBuilder によっ 
て置き換えられた 
 教訓:必要性が疑わしい場合には、内部的な同期を行わず、 
スレッドセーフでないことを文書化する
まとめ 
 デッドロックやデータ破壊を回避するため、同期 
された領域から異質なメソッドを呼び出さない 
(決して!) 
 より一般的には:同期された領域内で行う処理の量を 
制限する 
 可変クラスを設計する場合は、内部同期を検討す 
る 
 並行性のため、過剰には同期せず、内部同期の採用が 
妥当でない場合はその旨をドキュメント化する 
 詳しくは『Java Concurrency in Practice』を読も 
う(邦訳もあるよ)
項目68 
スレッドよりエグゼキューターとタスク 
を選ぶ
エグゼキューターフレームワーク 
に 
親しもう 
// ワークキューを作成 
ExecutorService executor = 
Executors.newSingleThreadExecutor(); 
// runnable を実行のために発行 
executor.execute(runnable); 
// 終了を指示 
executor.shutdown(); 
 楽ちん便利
エグゼキューターサービスの 
多彩な機能 
 特定のタスクが完了するのを待つ 
 タスクの集まりの中のどれかのタスクや、す 
べてのタスクが完了するのを待つ 
 エグゼキューターサービスがきちんと完了す 
るのを待つ 
 タスクが完了するごとに、1 つずつタスクの 
結果を取り出す 
 スレッドプールを作成する
エグゼキューターサービスの選択 
 小さなプログラムや、軽い負荷のサーバーな 
ら: 
 Executors.newCachedThreadPool 
 設定不要、一般に「正しいことを行う」 
 高負荷の製品サーバーなら: 
 Executors.newFixedThreadPool 
 固定数のスレッドを持つプールを提供する 
 ThreadPoolExecutor を直接使用 
 最大限の制御が可能
Thread を直接使うのはもうやめよ 
う 
 Thread 
 処理の単位と、処理を実行するための機構の両方 
 Runnable / Callable / エグゼキューターサービ 
ス 
 <タスク>(処理の単位)とその実行機構を、そ 
れぞれ適切に抽象化する
Timer を直接使うのももうやめよ 
う 
 Timer 
 タスク実行のために単一スレッドしか使用してい 
ない 
 タイミングの精度に不安あり 
 例外がスローされると、動作しなくなる 
 ScheduledThreadPoolExecutor 
 複数スレッドをサポート 
 チェックされない例外をスローする例外からも回 
復
まとめ 
 詳しくは『Java Concurrency in Practice』を 
読もう(邦訳もあるよ)

Más contenido relacionado

La actualidad más candente

非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎信之 岩永
 
C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介yohhoy
 
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE).NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)Tusyoshi Matsuzaki
 
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
 
ret2dl resolve
ret2dl resolveret2dl resolve
ret2dl resolvesounakano
 
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
 
effective modern c++ chapeter36
effective modern c++ chapeter36effective modern c++ chapeter36
effective modern c++ chapeter36Tatsuki SHIMIZU
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するshigeki_ohtsu
 
Preludeのprecompile
PreludeのprecompilePreludeのprecompile
PreludeのprecompileGlass_saga
 
エキ 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
 
Return Oriented Programming
Return Oriented ProgrammingReturn Oriented Programming
Return Oriented Programmingsounakano
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALegtra
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用MITSUNARI Shigeo
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチKazuki Onishi
 

La actualidad más candente (20)

非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
 
C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介
 
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE).NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
 
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
 
ret2dl resolve
ret2dl resolveret2dl resolve
ret2dl resolve
 
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)
 
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
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
 
Effective modern-c++#9
Effective modern-c++#9Effective modern-c++#9
Effective modern-c++#9
 
Preludeのprecompile
PreludeのprecompilePreludeのprecompile
Preludeのprecompile
 
エキ 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
 
Return Oriented Programming
Return Oriented ProgrammingReturn Oriented Programming
Return Oriented Programming
 
Stack pivot
Stack pivotStack pivot
Stack pivot
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチ
 

Destacado

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
 

Destacado (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
 
Effective Java 輪読会 項目53-56
Effective Java 輪読会 項目53-56Effective Java 輪読会 項目53-56
Effective Java 輪読会 項目53-56
 
JavaScript 勉強会 ― 型と値
JavaScript 勉強会 ― 型と値JavaScript 勉強会 ― 型と値
JavaScript 勉強会 ― 型と値
 
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 輪読会 項目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 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44
 
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 a Effective Java 輪読会 項目66-68

第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
Java 並行処理の基礎update1
Java 並行処理の基礎update1Java 並行処理の基礎update1
Java 並行処理の基礎update1Kazuhiro Eguchi
 
traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験Toshio Ehara
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義JPCERT Coordination Center
 
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けーTanUkkii
 
Unit test in android
Unit test in androidUnit test in android
Unit test in androidTatsuya Maki
 
from old Java to modern Java
from old Java to modern Javafrom old Java to modern Java
from old Java to modern Java心 谷本
 
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolateskoichik
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Uehara Junji
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)taskie
 
cloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfcloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfKosuke Saigusa
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Nextdynamis
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
今日からはじめるGPars
今日からはじめるGPars今日からはじめるGPars
今日からはじめるGParsfumokmm
 
Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてkimukou_26 Kimukou
 
Project Loom - 限定継続と軽量スレッド -
Project Loom - 限定継続と軽量スレッド - Project Loom - 限定継続と軽量スレッド -
Project Loom - 限定継続と軽量スレッド - Yuichi Sakuraba
 

Similar a Effective Java 輪読会 項目66-68 (20)

第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
Java 並行処理の基礎update1
Java 並行処理の基礎update1Java 並行処理の基礎update1
Java 並行処理の基礎update1
 
Junit4
Junit4Junit4
Junit4
 
traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義
 
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
 
Unit test in android
Unit test in androidUnit test in android
Unit test in android
 
from old Java to modern Java
from old Java to modern Javafrom old Java to modern Java
from old Java to modern Java
 
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates
 
Xtext&Xtend documents
Xtext&Xtend documentsXtext&Xtend documents
Xtext&Xtend documents
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)
 
cloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfcloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdf
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
今日からはじめるGPars
今日からはじめるGPars今日からはじめるGPars
今日からはじめるGPars
 
Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用について
 
Project Loom - 限定継続と軽量スレッド -
Project Loom - 限定継続と軽量スレッド - Project Loom - 限定継続と軽量スレッド -
Project Loom - 限定継続と軽量スレッド -
 

Más de 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
 

Más de 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
 

Último

プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価sugiuralab
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールsugiuralab
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 

Último (7)

プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 

Effective Java 輪読会 項目66-68

  • 1. Effective Java 輪読会第8回 (項目66~68) 2014/3/5 開発部野口
  • 3. synchronized  以下の2 つを保証する  スレッドが、不整合な状態のオブジェクトを見な いこと  スレッドから、同じロックで保護されていた以前 のすべての変更の結果が見えること
  • 4. アトミックな型  long 型とdouble 型以外の変数の読み書きがア トミックであることは、言語仕様によって保 証されている  では、パフォーマンスのため、アトミックなデー タへの読み書きでは同期を避けるべき?  そうではない
  • 5. メモリモデル  言語仕様では、フィールドを読み出すときに スレッドがランダムな値を読み出さないこと を保証している  が、1 つのスレッドが書き込んだ値が他のス レッドからも見えることは保証していない  ので、アトミックなデータに対しても同期は 有用
  • 6. 不完全な同期の例 public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { public void run() { int i = 0; while (!stopRequested) i++; }}); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; // この変更がbackgroundThread には伝わらな い! // ので、プログラムが終了しない(活性エラー) }}
  • 7. 巻き上げ  HotSpot Server VM は、以下のような変更を行う(この 変更は許容されている) ↓ while (!stopRequested) i++; if (!stopRequested) while (true) // !!! i++;
  • 8. 不完全な同期の修正案 public class StopThread { private static boolean stopRequested; public static synchronized void requestStop() { stopRequested = true; } public static synchronized boolean stopRequested() { return stopRequested; } public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { public void run() { int i = 0; while (!stopRequested()) i++; }}); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); requestStop(); // 変更がbackgroundThread にも反映される // ので、プログラムは1 秒で終了する }}
  • 9. 修正案の注意点  読み込み操作(stopRequested)と書き込み操 作(requestStop)の両方が同期されている必 要がある
  • 10. volatile による修正案 public class StopThread { private static volatile boolean stopRequested; public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { public void run() { int i = 0; while (!stopRequested) i++; } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; // 反映される }
  • 11. volatile の失敗例 // 不完全- 同期が必要! private static volatile int nextSerialNumber = 0; public static int generateSerialNumber() { return nextSerialNumber++; // この操作はアトミックではない! // ので、タイミング次第では、複数のスレッドで // 同じシリアルナンバーを得てしまう(安全性エ ラー) }
  • 12. AtomicLong public static synchronized long generateSerialNumber() { if (nextSerialNumber == Long.MAX_VALUE) throw new なんとかException(); return nextSerialNumber++; ↑同等!(かつ、後者の方が速い可能性が高い)↓ } private static final AtomicLong nextSerialNum = new AtomicLong(); public static long generateSerialNumber() { return nextSerialNum.getAndIncrement(); }
  • 13. 可変データを共有しない  最善!  その際は、文書化しよう(方針が維持される ように)  フレームワークやライブラリを深く理解しよ う(内部でスレッドが用いられているかもし れない)
  • 14. 事実上不変  「少しの間スレッドがデータオブジェクトを 変更してから、オブジェクト参照を共有する 処理だけを同期する」  「オブジェクトが再び変更されない限り、他のス レッドはさらに同期することなくオブジェクトを 読み出すことができる」 // (”Java Concurrency in Practice” より引用) public Map<String, Date> lastLogin = Collections.synchronizedMap(new HashMap<String, Date>());
  • 15. 安全な公開  フィールドをstatic にして、クラス初期化に よろしくお願いする  フィールドをvolatile にする  フィールドをfinal にする  フィールドをロックで保護する  コンカレントコレクションを用いる
  • 16. まとめ  複数のスレッドが可変データを共有する場合、そ のデータを読み書きするスレッドは同期を行う  同期なしでは、あるスレッドの変更が他のスレッドか ら見えることは保証されない  同期しないことへのペナルティ:活性エラーと安 全性エラー  デバッグ困難!  タイミング依存、JVM 依存  スレッド間通信だけが必要な場合は、volatile も ある  ただし、正しく使用するのは難しい  詳しくは『Java Concurrency in Practice』を読も う(邦訳もあるよ)
  • 18. 同期されたメソッドやブロック内 で、制御をクライアントに譲らな い  オーバーライドされるように設計されている メソッドや関数オブジェクトを、同期された 領域内で呼び出さない  <異質>なメソッドだから  メソッドが何をするかわからないため、例外、デッド ロック、データ破壊の可能性がある
  • 19. 異質なメソッド呼び出し (例外編)  ObservableSet(pp.256-257)と、 SetObserver(pp.257)  SetObserver#added で ObservableSet#removeObserver を呼び出すと、 ConcurrentModificationException がスローされ る!(pp.257-258)  リストをイテレート中に、そのリストから要素を削除 しようとしているから
  • 20. 異質なメソッド呼び出し (デッドロック編)  再びObservableSet(pp.256-257)と、 SetObserver(pp.257)  SetObserver#added で、ExecutorService 経由で ObservableSet#removeObserver を呼び出すと、 デッドロックが発生する!(pp.258)  ObservableSet.observers のロックは、既にメインス レッドによって獲得されているから
  • 21. 異質なメソッド呼び出し (地獄編)  もし、 1. 同期された領域により保護されている不変式が一時 的に不正になっている間に、 2. 同期された領域内から異質なメソッドを呼び出した ら、 3. その異質なメソッドは首尾よくロックを獲得し(再 帰的ロック)、 4. オブジェクトの内部状態をこっそり不正にしてしま う!(かもしれない)  ロックが用をなしていない  再帰的ロックは、活性エラーを安全性エラーに変える 可能性がある
  • 22. 異質なメソッド呼び出しの回避 (オープンコール) private void notifyElementAdded(E element) { List<SetObserver<E>> snapshot = null; synchronized(observers) { snapshot = new ArrayList<SetObserver<E>>(observers); } for (SetObserver<E> observer : snapshot) observer.added(this, element); }  SetObserver#added の処理時間が長い場合、並行性 を増大させるメリットも期待できる
  • 23. 異質なメソッド呼び出しの回避 (CopyOnWriteArrayList) private final List<SetObserver<E>> observers = new CopyOnWriteArrayList<SetObserver<E>>(); public void addObserver(SetObserver<E> observer) { observers.add(observer); } public void notifyElementAdded(E element) { observer.added(this, element); } private void addObserver(SetObserver<E> observer) { for (SetObserver<E> observer : observers) observers.add(observer); }
  • 24. 同期のコスト  ロックに費やされるCPU 時間  よりも、並行処理を行う機会損失  および、すべてのコアがメモリの一貫した ビューを持つことを保証する必要性から生じ る遅延
  • 25. 内部同期と外部同期  クラスが並行して使用されるのであれば、可変クラス をスレッドセーフにすべき  static フィールドへのアクセスは、必ず内部同期が必 要  関係のないクライアント同士が、同じルールで同期できる とは限らないから  StringBuffer とStringBuilder  StringBuffer は、ほとんどの場合に単一スレッドから使用 されるのに、内部的に同期を行っている  リリース1.5 で、同期されていないStringBuilder によっ て置き換えられた  教訓:必要性が疑わしい場合には、内部的な同期を行わず、 スレッドセーフでないことを文書化する
  • 26. まとめ  デッドロックやデータ破壊を回避するため、同期 された領域から異質なメソッドを呼び出さない (決して!)  より一般的には:同期された領域内で行う処理の量を 制限する  可変クラスを設計する場合は、内部同期を検討す る  並行性のため、過剰には同期せず、内部同期の採用が 妥当でない場合はその旨をドキュメント化する  詳しくは『Java Concurrency in Practice』を読も う(邦訳もあるよ)
  • 28. エグゼキューターフレームワーク に 親しもう // ワークキューを作成 ExecutorService executor = Executors.newSingleThreadExecutor(); // runnable を実行のために発行 executor.execute(runnable); // 終了を指示 executor.shutdown();  楽ちん便利
  • 29. エグゼキューターサービスの 多彩な機能  特定のタスクが完了するのを待つ  タスクの集まりの中のどれかのタスクや、す べてのタスクが完了するのを待つ  エグゼキューターサービスがきちんと完了す るのを待つ  タスクが完了するごとに、1 つずつタスクの 結果を取り出す  スレッドプールを作成する
  • 30. エグゼキューターサービスの選択  小さなプログラムや、軽い負荷のサーバーな ら:  Executors.newCachedThreadPool  設定不要、一般に「正しいことを行う」  高負荷の製品サーバーなら:  Executors.newFixedThreadPool  固定数のスレッドを持つプールを提供する  ThreadPoolExecutor を直接使用  最大限の制御が可能
  • 31. Thread を直接使うのはもうやめよ う  Thread  処理の単位と、処理を実行するための機構の両方  Runnable / Callable / エグゼキューターサービ ス  <タスク>(処理の単位)とその実行機構を、そ れぞれ適切に抽象化する
  • 32. Timer を直接使うのももうやめよ う  Timer  タスク実行のために単一スレッドしか使用してい ない  タイミングの精度に不安あり  例外がスローされると、動作しなくなる  ScheduledThreadPoolExecutor  複数スレッドをサポート  チェックされない例外をスローする例外からも回 復
  • 33. まとめ  詳しくは『Java Concurrency in Practice』を 読もう(邦訳もあるよ)