Java中是否可能有无限循环线程和JFrame?
我试图创建一个小游戏,其中一个线程运行一个无限循环,该循环将执行引擎任务,而JFrame中的所有内容都将输出到屏幕上 但我面临一个大问题,我无法解决,也无法在互联网上找到任何答案。当我在线程的无限循环中并没有立即输出到控制台时,那个线程(在引擎类中)似乎被程序终止,只剩下JFrame。但当在无限循环中有一些输出到控制台时,线程(在引擎类中)就完全按照预期工作,这让我抓狂:( 主要类别:Java中是否可能有无限循环线程和JFrame?,java,multithreading,loops,jframe,infinite,Java,Multithreading,Loops,Jframe,Infinite,我试图创建一个小游戏,其中一个线程运行一个无限循环,该循环将执行引擎任务,而JFrame中的所有内容都将输出到屏幕上 但我面临一个大问题,我无法解决,也无法在互联网上找到任何答案。当我在线程的无限循环中并没有立即输出到控制台时,那个线程(在引擎类中)似乎被程序终止,只剩下JFrame。但当在无限循环中有一些输出到控制台时,线程(在引擎类中)就完全按照预期工作,这让我抓狂:( 主要类别: package ccarsimulator; import javax.swing.SwingUtiliti
package ccarsimulator;
import javax.swing.SwingUtilities;
public class CCarSimulator {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Window window = new Window("CCarsimulator");
});
}
}
窗口类:
package ccarsimulator;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Window extends JFrame{
Engine oEngine = new Engine(this);
JLabel LabelOutput = new JLabel();
JPanel PanelCanvas = new JPanel();
JLabel LabelSpeed;
JLabel LabelRPM;
JLabel LabelGearSet;
JLabel LabelTotalTime;
JLabel LabelFPS;
JLabel LabelCPS;
public Window(String WindowTitle){
super(WindowTitle);
this.addKeyListener(new KeyListener(){
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent oKey) {
System.out.println("Key Pressed");
oEngine.bKeyPressed[oKey.getKeyCode()] = true;
}
@Override
public void keyReleased(KeyEvent oKey) {
oEngine.bKeyPressed[oKey.getKeyCode()] = false;
}
});
this.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent oEvent){
System.out.println("Closing a Window");
oEngine.bStopEngine = true;
}
});
this.add(PanelCanvas);
PanelCanvas.add(LabelOutput);
LabelOutput.setText("Test");
this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setFocusable(true);
}
}
发动机等级:
package ccarsimulator;
import java.awt.event.KeyEvent;
public class Engine extends Thread{
Thread thisSelf = this;
public boolean bStopEngine = false;
public Window oWindow;
public boolean []bKeyPressed = new boolean[KeyEvent.CHAR_UNDEFINED + 1];
public boolean []bKeyReleased = new boolean[KeyEvent.CHAR_UNDEFINED + 1];
public Engine(Window oWindow){
this.oWindow = oWindow;
thisSelf.start();
}
@Override
public void run(){
System.out.println("Waiting for window");
//while(!oWindow.isVisible() && !bStopEngine);
System.out.println("Engine is up and Running");
while(!bStopEngine){
//
//---------------------------------------
//Add some output to console to make this loop working...
//---------------------------------------
//
if(bKeyPressed[KeyEvent.VK_ESCAPE]){
System.out.println("Pressed Escape");
}
}
System.out.println("Engine was disabled");
}
}
在引擎的类线程无限循环中,没有一些输出到控制台的结果是
Waiting for window
Engine is up and Running
Key Pressed
Key Pressed
Key Pressed
Key Pressed
Closing a Window
一些输出的结果是:
Waiting for window
Engine is up and Running
Some debug
Some debug
...
...
Some debug
Closing a Window
Some debug
Some debug
Engine was disabled
好吧,我的Java大师朋友帮我解决了这一切。 并且在几秒钟内回答了我为什么不喜欢这个问题,因为我发表了这个问题,我仍然觉得不公平,因为我不能很清楚地描述它,如果我这样做了,我会在不问的情况下找到问题的答案 问题是,我必须在由两个线程(我的引擎线程和Swing线程)处理的变量上添加
volatile
关键字
没有关键字volatile
时,我的Swing线程正在更改这两个引擎线程(bOpenEngine
和bKeyPressed
)RAM内存中的变量,而这两个引擎线程的变量在CPU缓存内存中,所以引擎线程无法知道某些更改,因为这两个变量没有在正确的位置更改
这也帮助我理解了为什么我的代码只能将这两个变量中的一个设置为volatile。这是因为Java默认情况下应该将大约4KB的内存块页面加载到CPU内存中。因此,如果幸运的话,我的volatile变量通过Swing线程使用的另一个变量进入该页面,而不使用volatile关键字,那么该页面就是s直到设置了线程同步,并且仍然将我的变量与Swing线程同步,所以它仍然有效
只是告诉将来帮助别人摆脱对类似问题的困惑,或者在我再次忘记这一切的时候帮助自己;)伙计们,请不要投票否决这条帖子,请解释我做错了什么。。。或者解释一下你为什么不选这个帖子。。。因为这对你来说是不公平的