Java缓冲区策略导致严重滞后
我有一个小引擎,在我的OSX笔记本电脑上运行得很好,但在功能不太强大的Linux PC上运行时会崩溃或严重滞后。我最小化了代码,使其仅为一个小类,但也存在完全相同的滞后性。我认为这与缓冲区策略和线程有关。下面是课程:Java缓冲区策略导致严重滞后,java,java-2d,Java,Java 2d,我有一个小引擎,在我的OSX笔记本电脑上运行得很好,但在功能不太强大的Linux PC上运行时会崩溃或严重滞后。我最小化了代码,使其仅为一个小类,但也存在完全相同的滞后性。我认为这与缓冲区策略和线程有关。下面是课程: public class Test extends Canvas implements Runnable { private Thread thread; private boolean running = false; public Test()
public class Test extends Canvas implements Runnable {
private Thread thread;
private boolean running = false;
public Test()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(1000, 1000));
frame.add(this);
frame.setVisible(true);
start();
}
public static void main(String[] args)
{
new Test();
}
public synchronized void start()
{
this.thread = new Thread(this);
this.thread.start();
this.running = true;
}
public synchronized void stop()
{
try
{
this.thread.join();
this.running = false;
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
while(running)
{
render();
}
}
private void render()
{
BufferStrategy bs = this.getBufferStrategy();
if(bs == null)
{
this.createBufferStrategy(2);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, 1000, 1000);
g.dispose();
bs.show();
}
}
我看到画布被漆成黑色之前的延迟。在将JFrame设置为可见之前,必须在画布上绘制一些内容 以下是我对您的代码所做的更改
package com.ggl.testing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawingTest extends JPanel {
private static final long serialVersionUID = 2584117430541789858L;
private DrawingTestRunnable drawingTestRunnable;
private boolean isWhite;
public DrawingTest() {
this.setPreferredSize(new Dimension(1200, 700));
this.isWhite = true;
JFrame frame = new JFrame("Drawing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setVisible(true);
start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new DrawingTest();
}
});
}
public synchronized void start() {
drawingTestRunnable = new DrawingTestRunnable(this);
new Thread(drawingTestRunnable).start();
}
public boolean isWhite() {
return isWhite;
}
public void setWhite(boolean isWhite) {
this.isWhite = isWhite;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (isWhite) {
g.setColor(Color.WHITE);
} else {
g.setColor(Color.BLACK);
}
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.dispose();
}
public class DrawingTestRunnable implements Runnable {
private boolean isWhite;
private volatile boolean running;
private DrawingTest drawingTest;
public DrawingTestRunnable(DrawingTest drawingTest) {
this.drawingTest = drawingTest;
this.running = true;
}
@Override
public void run() {
long duration = 250L;
long startTime = System.currentTimeMillis();
while (running) {
repaintPanel();
long elapsedTime = System.currentTimeMillis() - startTime;
long loopDuration = Math.max((duration - elapsedTime), 5L);
sleep(loopDuration);
startTime = System.currentTimeMillis();
}
}
private void repaintPanel() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
drawingTest.repaint();
isWhite = !isWhite;
drawingTest.setWhite(isWhite);
}
});
}
private void sleep(long duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
}
}
public synchronized void setRunning(boolean running) {
this.running = running;
}
}
}
我看到画布被漆成黑色之前的延迟。在将JFrame设置为可见之前,必须在画布上绘制一些内容 以下是我对您的代码所做的更改
package com.ggl.testing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawingTest extends JPanel {
private static final long serialVersionUID = 2584117430541789858L;
private DrawingTestRunnable drawingTestRunnable;
private boolean isWhite;
public DrawingTest() {
this.setPreferredSize(new Dimension(1200, 700));
this.isWhite = true;
JFrame frame = new JFrame("Drawing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setVisible(true);
start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new DrawingTest();
}
});
}
public synchronized void start() {
drawingTestRunnable = new DrawingTestRunnable(this);
new Thread(drawingTestRunnable).start();
}
public boolean isWhite() {
return isWhite;
}
public void setWhite(boolean isWhite) {
this.isWhite = isWhite;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (isWhite) {
g.setColor(Color.WHITE);
} else {
g.setColor(Color.BLACK);
}
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.dispose();
}
public class DrawingTestRunnable implements Runnable {
private boolean isWhite;
private volatile boolean running;
private DrawingTest drawingTest;
public DrawingTestRunnable(DrawingTest drawingTest) {
this.drawingTest = drawingTest;
this.running = true;
}
@Override
public void run() {
long duration = 250L;
long startTime = System.currentTimeMillis();
while (running) {
repaintPanel();
long elapsedTime = System.currentTimeMillis() - startTime;
long loopDuration = Math.max((duration - elapsedTime), 5L);
sleep(loopDuration);
startTime = System.currentTimeMillis();
}
}
private void repaintPanel() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
drawingTest.repaint();
isWhite = !isWhite;
drawingTest.setWhite(isWhite);
}
});
}
private void sleep(long duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
}
}
public synchronized void setRunning(boolean running) {
this.running = running;
}
}
}
对于阅读本文的其他人来说,混合使用Swing轻量级和AWT重量级组件不是一个好主意。如果您想在Swing应用程序中绘图,请使用JPanel。如果创建2D游戏,是否建议使用AWT over Swing?否。有关使用Swing的图形应用程序示例,请参阅我的答案。对于阅读本文的其他人,混合使用Swing轻量级组件和AWT重量级组件不是一个好主意。如果您想在Swing应用程序中绘图,请使用JPanel。如果创建2D游戏,是否建议使用AWT over Swing?否。有关使用Swing的图形应用程序示例,请参阅我的答案。