Я делаю пробную игру на Java и решил (для практики, но в основном для удовольствия) создать свой собственный простой компонент с поточной безопасной двойной буферизацией.Тем не менее, я не очень опытен, когда дело доходит до параллелизма (особенно в отношении Swing), и мне интересно, есть ли какие-либо проблемы с моей реализацией, которые мне не хватает.
Реализация выглядит следующим образом:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class GamePanel extends JPanel
{
private static final long serialVersionUID = 1L;
private BufferedImage mBackImage = null;
private BufferedImage mFrontImage = null;
public BufferedImage getBackImage ()
{
return mBackImage;
}
public void swap ()
{
BufferedImage new_back;
//
synchronized (this)
{
new_back = mFrontImage;
mFrontImage = mBackImage;
}
//
int width = getWidth (), height = getHeight ();
if (width > 0 && height > 0)
{
if (new_back == null || new_back.getWidth () != width
|| new_back.getHeight () != height)
new_back = new BufferedImage (width, height,
BufferedImage.TYPE_INT_ARGB);
//
mBackImage = new_back;
}
else
mBackImage = null;
}
@Override
public void paintComponent (Graphics g)
{
synchronized (this)
{
if (mFrontImage == null)
super.paintComponent (g);
else
g.drawImage (mFrontImage, 0, 0, null);
}
}
}
Я предполагаю, что getBackImage()
и swap()
будут вызываться только одним потоком (потоком игрового цикла).Краски запускаются с помощью таймера Swing и находятся в EDT.Я полагаю, что простых синхронизированных блоков вокруг использования mFrontImage
должно быть достаточно для защиты от нежелательного поведения, позволяя потоку игрового цикла визуализировать заднее изображение и вызывать swap, не беспокоясь о перерисовках Swing.Я что-то упустил?