java无法通知()线程?

时间:2016-07-02 07:49:15

标签: java multithreading

目前我正在尝试构建一个蛇游戏作为我在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);
}
}

1 个答案:

答案 0 :(得分:0)

  

目前我正在尝试构建一个蛇游戏作为我在java中的第一个项目,并且正在使用线程。

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

  • Java语言,
  • Java标准库,
  • Swing,以及如何设计桌面GUI应用程序,
  • 线程如何工作,以及如何利用它们。

慢下来。一次带一个。

  

我希望对象在到达屏幕边框时等待,然后在键输入进入时通知......

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

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

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

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

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