/ /この単純なSwingベースのクラスはスレッドセーフですか? - Java、スイング、スレッドセーフ

この単純なSwingベースのクラスはスレッドセーフですか? - Java、スイング、スレッドセーフ

私は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() 単一のスレッド(ゲームループスレッド)によってのみ呼び出されます。塗料はスイングタイマーでトリガーされ、EDTにも塗りつぶされます。私は単純な同期ブロックの使用を中心に mFrontImage Swingの再描画を心配することなく、ゲームループスレッドをバックイメージにレンダリングし、スワップを呼び出すことができるように、不要な動作から保護するのに十分なはずです。何か不足していますか?

回答:

回答№1は1

ゲームスレッドの場合:

BufferedImage image = gamePanel.getBackPanel();
gamePanel.swap();

あなたのプログラムは現在、イベントディスパッチキューとゲームスレッドは同じ画像にアクセスできます。 EDTが画像をスクリーンに描いていた間に、あなたが画像に描いていたならば、面白いことを意味することができました。

読み書きの目的ですべてのアクセスが同期ブロック内で行われるため、frontImageフィールド自体はスレッドセーフですが、paintComponentメソッドを使用すると、同期ブロックで費やされる時間を短縮することができます。

@Override
public void paintComponent (Graphics g)
{
BufferedImage localFrontImage;
synchronized (this)
{
localFrontImage = mFrontImage;
}
if (localFrontImage == null)
super.paintComponent (g);
else
g.drawImage (localFrontImage, 0, 0, null);

}

回答№2の場合は1
  • スイングは純粋なシングルスレッドであり、すべてのイベントはEDTで行う必要があります。 synchronized (this)

  • つかいます アイコン の中に JLabel 派遣のための Swing GUIの画像

  • いずれかの swap"s types、あなたが見ている CardLayout