/ / Това просто клавиатура, базирана на Swing, е безопасна? - java, swing, thread-safety

Дали тази проста клавиатура, базирана на Swing, е безопасна? - java, swing, thread-safety

Правя игра на доказателство за концепция в 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);

}

1 за отговор № 2
  • Swing е чиста единична резба и всяко събитие трябва да се направи на EDT, тогава не мога да видя причина synchronized (this)

  • употреба икона в JLabel за изтласкване Изображения в Swing GUI

  • за всеки от тях swap"s types, погледнете CardLayout