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

質問編集履歴

3

補足追加

2020/10/12 11:23

投稿

ichiro200555
ichiro200555

スコア2

title CHANGED
File without changes
body CHANGED
@@ -164,6 +164,9 @@
164
164
 
165
165
  **2020.10.12追加**
166
166
 
167
+ __以下の記事は、Mutexクラスのlock()のif文をwhile文に修正した状態でプログラムを実行した場合のものです。
168
+ if文だと、そもそも競合状態になる場合があることがわかりました(quickquipさんの回答参照)。__
169
+
167
170
  jdbの表示の読み方が間違っていたようです。jdbのlockコマンドでロックに関する情報を確認したところ、lock()の中を実行中のスレッドは1つしかありませんでした。ロック獲得待ちをしているスレッドでwhereコマンドを実行した時に表示される行番号は、実行しようとしているメソッドの中でjdbがブレークポイントをはれる最初の行番号を表示するようです(「try {」やコメント行にはブレークポイントが設定できない。そのため、その次の行の「if (isLock) {」の行番号が表示される)。
168
171
 
169
172
  ```

2

jdbの表示の読み方に関する記事を追加

2020/10/12 11:23

投稿

ichiro200555
ichiro200555

スコア2

title CHANGED
File without changes
body CHANGED
@@ -121,8 +121,8 @@
121
121
 
122
122
  ### 試したこと
123
123
 
124
- jdbでMutexクラスの「System.out.println("isLock=" + isLock);」の行にブレークポイントをはり、他のスレッドの様子を確認したところ、lock()内に2つのスレッドがいました(以下のjdbのログのスレッド0x1beとスレッド0x1bf)。
124
+ ~~jdbでMutexクラスの「System.out.println("isLock=" + isLock);」の行にブレークポイントをはり、他のスレッドの様子を確認したところ、lock()内に2つのスレッドがいました(以下のjdbのログのスレッド0x1beとスレッド0x1bf)。
125
- スレッド0x1beはlock()の「if (isLock) {」の部分を、スレッド0x1bfはlock()の「System.out.println("isLock=" + isLock);」の部分を実行しているようです。
125
+ スレッド0x1beはlock()の「if (isLock) {」の部分を、スレッド0x1bfはlock()の「System.out.println("isLock=" + isLock);」の部分を実行しているようです。~~
126
126
 
127
127
  ```
128
128
  $ jdb Main
@@ -157,9 +157,54 @@
157
157
  Thread-1[1]
158
158
  ```
159
159
 
160
+ ~~
160
161
  lock()の中に2つスレッドがいて、正常にロックを実装できていないことが競合が起きている原因だと思いますが、なぜsynchronizedメソッドの中に同時に複数のスレッドが入れるのかがわかりません。
161
162
  新しくlock()を呼んだスレッドはもちろん、notify()によってウェイトセットから出てきたスレッドも、synchronizedによるロックの獲得待ちをするため、lock()には同時に1つのスレッドしか入れない認識です。
163
+ ~~
162
164
 
165
+ **2020.10.12追加**
166
+
167
+ jdbの表示の読み方が間違っていたようです。jdbのlockコマンドでロックに関する情報を確認したところ、lock()の中を実行中のスレッドは1つしかありませんでした。ロック獲得待ちをしているスレッドでwhereコマンドを実行した時に表示される行番号は、実行しようとしているメソッドの中でjdbがブレークポイントをはれる最初の行番号を表示するようです(「try {」やコメント行にはブレークポイントが設定できない。そのため、その次の行の「if (isLock) {」の行番号が表示される)。
168
+
169
+ ```
170
+ Thread-0[1] threads
171
+ グループsystem:
172
+ (java.lang.ref.Reference$ReferenceHandler)0x173 Reference Handlerは実行中です
173
+ (java.lang.ref.Finalizer$FinalizerThread)0x174 Finalizer は条件を待機中です
174
+ (java.lang.Thread)0x175 Signal Dispatcherは実行中です
175
+ グループmain:
176
+ (UserThread)0x1be Thread-0 は実行中です(ブレークポイント)
177
+ (UserThread)0x1bf Thread-1 はモニター内で待機中です
178
+ (UserThread)0x1c1 Thread-2 はモニター内で待機中です
179
+ (java.lang.Thread)0x1c6 DestroyJavaVM は実行中です
180
+ グループInnocuousThreadGroup:
181
+ (jdk.internal.misc.InnocuousThread)0x1a2 Common-Cleaner は条件を待機中です
182
+ Thread-0[1] where
183
+ [1] Mutex.lock (Mutex.java:10)
184
+ [2] Gate.pass (Gate.java:9)
185
+ [3] UserThread.run (UserThread.java:16)
186
+ Thread-0[1] thread 0x1bf
187
+ Thread-1[1] where
188
+ [1] Mutex.lock (Mutex.java:8)
189
+ [2] Gate.pass (Gate.java:9)
190
+ [3] UserThread.run (UserThread.java:16)
191
+ Thread-1[1] thread 0x1c1
192
+ Thread-2[1] where
193
+ [1] Mutex.lock (Mutex.java:8)
194
+ [2] Gate.pass (Gate.java:9)
195
+ [3] UserThread.run (UserThread.java:16)
196
+
197
+ // lockコマンドでthis(lock()がロックする時に使うインスタンス)のロックの情報を表示してやると、
198
+ // 実行中のスレッド(ロックを獲得しているスレッド)はThread-0のみで、Thread-1とThread-2は
199
+ // ロック獲得待ちであることがわかる。
200
+ Thread-2[1] lock this
201
+ com.sun.tools.example.debug.expr.ParseException: Unable to complete expression. Thread not suspended for method invoke
202
+ 所有者: Thread-0、エントリ数: 1
203
+ スレッドを待機中: Thread-1
204
+ スレッドを待機中: Thread-2
205
+ Thread-2[1]
206
+ ```
207
+
163
208
  ### 補足情報(FW/ツールのバージョンなど)
164
209
  - OS
165
210
  macOS Catalina バージョン10.15.7

1

OSの情報を追加しました

2020/10/12 11:15

投稿

ichiro200555
ichiro200555

スコア2

title CHANGED
File without changes
body CHANGED
@@ -161,7 +161,9 @@
161
161
  新しくlock()を呼んだスレッドはもちろん、notify()によってウェイトセットから出てきたスレッドも、synchronizedによるロックの獲得待ちをするため、lock()には同時に1つのスレッドしか入れない認識です。
162
162
 
163
163
  ### 補足情報(FW/ツールのバージョンなど)
164
-
164
+ - OS
165
+ macOS Catalina バージョン10.15.7
166
+ - Javaのバージョン
165
167
  ```
166
168
  $ java -version
167
169
  openjdk version "11.0.8" 2020-07-14