teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

既定で非スレッドセーフを追記

2015/02/16 04:58

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -2,13 +2,11 @@
2
2
 
3
3
  .NET Frameworkの文脈ならば、大意としては「あるクラスについて、そのメソッドを異なるスレッドから同時に呼び出しても、仕様通りに動作すると保障される」という感じでしょう。これは、あるクラスのインスタンスに対して、同一メソッドを異なるスレッドから同時に呼び出す/異なるスレッドを異なるスレッドから同時に呼び出す、の両方を含みます。
4
4
 
5
-
6
5
  > スレッドセーフとは複数のスレッドから同時に利用されても正常に動作するよう、
7
6
  > ロックの取得を用い、期間内を単一スレッドのみ通過できるものと認識しております。
8
7
 
9
8
  スレッドセーフは対外的な「仕様」であり、ロックはその「内部実装」と考えたほうがよいです。スレッドセーフを実現するために、内部実装としてロック機構を用いることがよくあります。ただし、ロック機構を用いないスレッドセーフの実現方式もあります。
10
9
 
11
-
12
10
  > 上記記事でいう各メソッドのスレッドセーフの保障というのはコード内のロックの有無を認識し、
13
11
  > ロックが解除されるまで進めないというものでしょうか?
14
12
 
@@ -18,15 +16,15 @@
18
16
 
19
17
  スレッドセーフでないメソッドを複数スレッドから同時に呼び出すと、何が起こるかは保障されません。間違った結果を返すかもしれませんし、何らかの例外をスローしてくるかもしれませんし、偶然に正しく動くかもしれません。(.NET Framework提供クラスだと、丁寧に例外スローするものがいくつかあるようです)
20
18
 
21
-
22
19
  > またスレッドセーフではないメソッドも教えてください。
23
20
 
21
+ 基本的にスレッドセーフが明記されていない、内部状態をもつクラスのメソッドは、スレッドセーフではありません。言い換えると、内部実装で特別な考慮をしない限り、大半のメソッドはスレッドセーフではありません。例外として、状態を持たないメソッド=出力結果が入力引数にしか依存しないメソッドは、異なるメソッド呼び出し同士が互いに干渉しようがないため、スレッドセーフなメソッドと考えられます。
22
+
24
23
  たとえば、次のメソッド`getUniqueId`はスレッドセーフではありません。一意で重複しないID値を返すことを期待されますが、複数スレッドから同時に呼び出すと、仕様に反した”同じID値”を返す**可能性**があります。
25
-
26
24
  ```
27
25
  class Foo {
28
- static int counter = 0;
26
+ private int counter = 0;
29
- static int getUniqueId() {
27
+ public int getUniqueId() {
30
28
  return counter++;
31
29
  }
32
30
  }

1

誤記修正+α

2015/02/16 04:57

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  > 逆にスレッドセーフではないメソッドを用いた場合はロックを認識せず動作するということでしょうか?
18
18
 
19
- スレッドセーフでないメソッドを複数メソッドから呼び出すと、何が起こるかは保障されません。間違った結果を返すかもしれませんし、何らかの例外をスローしてくるかもしれませんし、偶然に正しく動くかもしれません。
19
+ スレッドセーフでないメソッドを複数スレッドから同時に呼び出すと、何が起こるかは保障されません。間違った結果を返すかもしれませんし、何らかの例外をスローしてくるかもしれませんし、偶然に正しく動くかもしれません。(.NET Framework提供クラスだと、丁寧に例外スローするものがいくつかあるようです)
20
20
 
21
21
 
22
22
  > またスレッドセーフではないメソッドも教えてください。