前提・実現したいこと
下のプログラムはタートルが衝突を検知するとその場で止まるというプログラムであるが、このプログラムは実行しているとすり抜けてしまう。
そこでsynchronizedを用いてプログラムを正常に動くようにしたい。
該当のソースコード
java
1public class TurtleCollision extends TurtleFrame { 2 public void start() { 3 Turtle m1 = new Turtle(50, 200, 90), m2 = new Turtle(350, 200, 270); 4 this.add(m1); 5 m1.speed((int)(Math.random() * 20.0) + 10); 6 this.add(m2); m2.tColor = Color.DEEPPINK; 7 m2.speed((int)(Math.random() * 20.0) + 10); 8 ExecutorService executor = Executors.newCachedThreadPool(); 9 final double step = 10.0; // 步幅 10 executor.execute(()-> { 11 while (m1.getX() < 400){ 12 if (0 == Double.compare(m1.getX() + step, m2.getX())) { // 衝突チェック 13 System.out.println("m1:collision at " + m1.getX()); 14 break; 15 } 16 m1.fd(step); // 1步進む 17 } 18 }); 19 executor.execute(()-> { 20 while (m2.getX() > 0){ 21 if (0 == Double.compare(m1.getX(), m2.getX() - step)) { // 衝突チェック 22 System.out.println("m2:collision at " + m2.getX()); 23 break; 24 } 25 m2.fd(step); // 1步進む 26 } 27 }); 28 } 29public static void main(String[] args) { 30 new TurtleCollision().start(); 31 } 32}
試したこと
synchronized void startSynchro()としてstart内のプログラムをコピーし、そこにsynchronizedを挿入して実行したが、うまくいかなかった。
java
1package prog2; 2import tg.*; 3import java.util.*; 4import java.util.concurrent.*; 5import javafx.scene.paint.Color; 6public class TurtleCollision extends TurtleFrame { 7 public void start() { 8 Turtle m1 = new Turtle(50, 200, 90), m2 = new Turtle(350, 200, 270); 9 this.add(m1); 10 m1.speed((int)(Math.random() * 20.0) + 10); 11 this.add(m2); m2.tColor = Color.DEEPPINK; 12 m2.speed((int)(Math.random() * 20.0) + 10); 13 ExecutorService executor = Executors.newCachedThreadPool(); 14 final double step = 10.0; // 步幅 15 executor.execute(()-> { 16 while (m1.getX() < 400){ 17 if (0 == Double.compare(m1.getX() + step, m2.getX())) { // 衝突チェック 18 System.out.println("m1:collision at " + m1.getX()); 19 break; 20 } 21 m1.fd(step); // 1步進む 22 } 23 }); 24 executor.execute(()-> { 25 while (m2.getX() > 0){ 26 if (0 == Double.compare(m1.getX(), m2.getX() - step)) { // 衝突チェック 27 System.out.println("m2:collision at " + m2.getX()); 28 break; 29 } 30 m2.fd(step); // 1步進む 31 } 32 }); 33 } 34 synchronized void startSynchro(){ 35 Turtle m1 = new Turtle(50, 200, 90), m2 = new Turtle(350, 200, 270); 36 this.add(m1); 37 m1.speed((int)(Math.random() * 20.0) + 10); 38 this.add(m2); m2.tColor = Color.DEEPPINK; 39 m2.speed((int)(Math.random() * 20.0) + 10); 40 ExecutorService executor = Executors.newCachedThreadPool(); 41 final double step = 10.0; // 步幅 42 synchronized(executor) { 43 executor.execute(()-> { 44 while (m1.getX() < 400){ 45 if (0 == Double.compare(m1.getX() + step, m2.getX())) { // 衝突チェック 46 System.out.println("m1:collision at " + m1.getX()); 47 break; 48 } 49 m1.fd(step); // 1步進む 50 } 51 }); 52 executor.execute(()-> { 53 while (m2.getX() > 0){ 54 if (0 == Double.compare(m1.getX(), m2.getX() - step)) { // 衝突チェック 55 System.out.println("m2:collision at " + m2.getX()); 56 break; 57 } 58 m2.fd(step); // 1步進む 59 } 60 }); 61 } 62 } 63public static void main(String[] args) { 64 new TurtleCollision().startSynchro(); 65 } 66}
このようにいれ、wait()なども試しましたが、一向にうまくいきません。どのようにsynchronizedを挿入すればいいのでしょうか
衝突を正しく検知したいためにsynchronizedを付けたいとのことですが、それで解決できる見込みがあるのでしょうか。
教材は『すべての人のためのJavaプログラミング』ですね。JavaFxが必要ですね。
https://www.i.h.kyoto-u.ac.jp/users/tsuiki/javaEveryone3/download.html
tgパッケージをコピーすれば動かせるのですが。
m1、m2が共有できるオブジェクトをsynchronizedしてください。<-- それほど容易ではないことがわかりました。衝突を判定するときに、m1,m2の内部状態がメモリに書き戻されていなければならないからです。synchronizedを使えば、L2キャッシュにデータがあったとしてもメモリ書き戻しが保証されます。
回答1件
あなたの回答
tips
プレビュー