タイトルの通りなのですが、デバッガで意図的にスレッドを止めてレースコンディションが起こせるとしたら
実際に起こりえると言えるのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
2024/09/23 05:42
回答3件
0
ベストアンサー
こんにちは。
質問部分に端的に回答すると、
デバッガで意図的に止めるなどの手段でレースコンディションを起こすことが可能なコードは、本質的に「レースコンディションが起きうるコード」ということになります。
レースコンディションを起こしてはいけない前提なら、そのコードは完全アウトです。
レースコンディションが起きないコードであれば、デバッガで止めるだけではレースコンディションは決して起こりません。
もちろんデバッガで止めた上で、内部状態を手で書き換えたりしたらレースコンディションを起こせるかもしれませんが、それは実際の動作中には起こりえないので、また別の話です。
投稿2024/09/24 08:28
総合スコア4433
0
デバッガで止めなくても・・・
スレッド間の共有資源(共有データ)に対する競合は、Theread.sleep(ms) などをスレッドのコードに入れたりすることでも起こせますね。
スレッドは独立したCPUで別々に実行しているようなものなので、共有資源(共有データ)をアクセスする場合には排他処理を必ず入れた方がいいと言えます。
以下のソースコードを実行すると、50に近い値が表示されそうですが、そうなりません。
java
1class MyThread extends Thread { 2 private int count; 3 public MyThread(int count) { 4 this.count = count; 5 } 6 @Override 7 public void run() { 8 for (int i=0; i<this.count; i++) { 9 int total = ThreadDemo.total; 10 try { 11 Thread.sleep(1); 12 } catch (InterruptedException e) { 13 ; 14 } 15 total += 1; 16 ThreadDemo.total = total; 17 } 18 } 19} 20public class ThreadDemo { 21 public static int total = 0; 22 public static void main(String[] args) throws Exception { 23 MyThread t1 = new MyThread(25); 24 MyThread t2 = new MyThread(25); 25 t1.start(); 26 t2.start(); 27 t1.join(); 28 t2.join(); 29 System.out.println(ThreadDemo.total); 30 } 31}
次のコードのように、排他処理を入れることで、総和が必ず50になります。
java
1import java.util.concurrent.locks.Lock; 2import java.util.concurrent.locks.ReentrantLock; 3 4class MyThread extends Thread { 5 private int count; 6 7 public MyThread(int count) { 8 this.count = count; 9 } 10 11 @Override 12 public void run() { 13 for (int i = 0; i < this.count; i++) { 14 ThreadDemo.lock.lock(); 15 try { 16 int total = ThreadDemo.total; 17 try { 18 Thread.sleep(1); 19 } catch (InterruptedException e) { 20 ; 21 } 22 total += 1; 23 ThreadDemo.total = total; 24 } finally { 25 ThreadDemo.lock.unlock(); 26 } 27 } 28 } 29} 30 31public class ThreadDemo { 32 public final static Lock lock = new ReentrantLock(true); 33 public static int total = 0; 34 35 public static void main(String[] args) throws Exception { 36 MyThread t1 = new MyThread(25); 37 MyThread t2 = new MyThread(25); 38 t1.start(); 39 t2.start(); 40 t1.join(); 41 t2.join(); 42 System.out.println(ThreadDemo.total); 43 } 44}
投稿2024/09/23 04:58
編集2024/09/23 05:21総合スコア86
0
レースコンディションは絶対に起こしてはいけないという前提です
だったら、「起きうるもの」という前提でプログラムを組む一択だと考えます。
投稿2024/09/23 04:54
総合スコア147054
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。