gpt4 book ai didi

java无法notify()线程?

转载 作者:太空宇宙 更新时间:2023-11-04 12:28:14 24 4
gpt4 key购买 nike

目前,我正在尝试构建一个贪吃蛇游戏作为我的第一个 Java 项目,并且正在使用线程。我想让一个对象在到达屏幕边界时等待,然后在输入按键时收到通知以继续移动另一个方向。在底部,我调用了notify()函数,但没有任何反应,线程继续处于wait()状态。任何帮助将不胜感激。

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);
}
}

最佳答案

Currently I am trying to build a snake game as my first project in java, and am using threads.

您试图同时学习太多东西;

  • Java 语言,
  • Java 标准库,
  • Swing,以及如何设计桌面 GUI 应用程序,
  • 线程如何工作,以及如何利用它们来发挥自己的优势。

慢点。一次拿一个。

<小时/>

I want to have an object wait when it reaches the border of the screen, and then be notified when a key input comes in...

这听起来不像是一个线程。将线程专用于游戏中的每个移动对象是一种非常有限的设计选择,并且让一个线程根据其状态等待不同的事物听起来像是一个糟糕的设计(IMO)。例如,我不会编写一个在蛇移动时等待实时时钟(即调用 sleep())的线程,然后在其他状态下等待按键。

已经有一个等待按键的线程:它称为事件调度线程 (EDT),它会在任何 Swing 程序中自动为您创建。而且,如果您想等待时钟(例如,为游戏中的对象设置动画),您最好使用 Swing Timer 来实现。

<小时/>

您应该知道,大多数 Swing 方法(例如,repaint())可能从 EDT 内调用。只有极少数,例如 SwingUtilities.invokeLater() 可以从其他线程调用。

<小时/>

o.wait()o.notify()o.notifyAll() 方法是低级原语,旨在以非常特定的模式使用,以实现更高级别的同步类。 Java 标准库已经在 java.util.concurrent 包中定义了许多有用的同步类。任何时候你想使用 wait/notify 时,你应该首先检查 java.util.concurrent 中是否有可以节省你一些精力的东西。

如果您必须使用wait/notify,那么您应该阅读Oracle的“Guarded Blocks”教程,并按照其应有的方式使用它:https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

关于java无法notify()线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38157844/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com