現在、私はJavaの最初のプロジェクトとしてスネークゲームを構築しようとしており、スレッドを使用しています。私はオブジェクトが画面の境界に達すると待ってから、別の方向への移動を続行するためにキー入力が来たときに通知を受けたい。 最後に、notify()関数を呼び出しますが、何も起こりません。スレッドは引き続きwait()状態になります。どんな助けでも大歓迎です。Javaスレッドがnotify()スレッドに通知できませんか?
package com.foreverblu.snake;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class snakeobject extends JPanel{
int x = 0;
int y = 0;
int z = 0;
int a = 0;
Thread animationThread;
Thread notifyThread;
public void paintComponent(Graphics g) {
super.paintComponents(g);
this.setBackground(Color.black);
g.setColor(Color.GREEN);
g.fill3DRect(x, y, 30, 30, true);
}
public void keepGoing() {
animationThread = new Thread(create);
notifyThread = new Thread(create2);
}
Runnable create = new Runnable() {
public void run() {
synchronized(this) {
while(z>=0 || z<=3) {
if(z==2 && y>0) {
y-=30;
repaint();
try{Thread.sleep(500);} catch (Exception ex) {}
}else if(z==1 && y<=450) {
y+=30;
repaint();
try {Thread.sleep(500);} catch (Exception ex) {}
}else if(z==0 && x<=450) {
x+=30;
repaint();
try{Thread.sleep(500);} catch (Exception ex) {}
}else if(z==3 && x>0) {
x-=30;
repaint();
try{Thread.sleep(500);} catch (Exception ex) {}
}else{
notifyThread.notify();
}
}
}
}
};
Runnable create2 = new Runnable() {
public void run() {
synchronized(this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
animationThread.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
do{try{Thread.sleep(500);} catch (Exception ex) {}
continue;
}while(a==0);
if(a==1) {
System.out.println("Notified");
a=0;
animationThread.notifyAll();
}
}
}
};
}
他のクラス: パッケージcom.foreverblu.snake。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class snakeframe extends JFrame{
int z = 0;
snakeobject swag = new snakeobject();
public snakeframe() {
super("The Great Title");
swag.keepGoing();
swag.notifyThread.start();
swag.animationThread.start();
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if(swag.animationThread.getState()==Thread.State.WAITING) {
swag.a=1;
System.out.println("Swag");
}
if(swag.animationThread.getState()==Thread.State.RUNNABLE) {
System.out.println("RUNNABLE");
}
if(e.getExtendedKeyCode()==e.VK_DOWN) {
swag.z=1;
}else if(e.getExtendedKeyCode()==e.VK_UP) {
swag.z=2;
}else if(e.getExtendedKeyCode()==e.VK_LEFT) {
swag.z=3;
}else if(e.getExtendedKeyCode()==e.VK_RIGHT) {
swag.z=0;
}
}
});
add(swag);
}
}
まあ、1のためにあなたは待機を使用しています/誤って通知します。 1台のモニターで同期するが別のモニターに通知する。関連するコードが実行されると、例外が発生するはずです。 EDTとメインスレッドで十分であるため、余分なスレッドを使用する必要はありません。 – Kayaman
最初のJavaプロジェクトとしてこれを行うことに言及します。私はあなたがスレッドを廃止し、より基本的なデザインを先に進めることをお勧めします。マルチスレッドはあなたが最初にやるべきことではありません。 – Gima