Reputation: 4878
I'm creating a game where levels can be loaded from a file. This is done on a separate thread, while everything else is done on the Event Dispatch Thread.
I tested the code by loading from a really large test file, and it turns out that the Event Dispatch Thread on occasions is unresponsive while the level is being loaded.
I can't seem to figure out the cause. Here's some of my code:
public class LevelSelectionWrapper extends GamePanel {
...
private JList list;
private File[] files;
...
//Lock object for synchronization
private Object lock = new Object();
//Runnable for loading levels from files on a separate thread
private Runnable loader = new Runnable() {
@Override
public void run() {
synchronized(lock) {
//Load levels from files
List<Level> levels = LevelLoader.load(files); // <-------------
...
SwingUtilities.invokeLater(new ListUpdater());
}
}
};
...
private void createOpenFileButton(Container container) {
final JFileChooser fc = ...
...
//Create open button
JButton openButton = new JButton("Open file");
openButton.setFocusable(false);
openButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int returnVal = fc.showOpenDialog(LevelSelectionWrapper.this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
synchronized(lock) { files = fc.getSelectedFiles(); }
//Load files on separate thread
new Thread(loader).start(); // <-------------
}
}
});
container.add(openButton);
}
}
I've added two arrows to the code:
Upvotes: 1
Views: 165
Reputation: 48844
I would definitely suggest getting rid of that lock
object (and the associated dependencies). Get the list of files inside actionPerformed()
and construct a copy to pass off to your runnable. Avoid using instance variables like files
like you currently are, as those are being shared across threads unnecessarily.
These synchronized
blocks are the most likely culprit to me. If that doesn't resolve your issue, I'd suggest adding some System.out.println()
calls around the areas you think are blocking to try to see exactly which call(s) are taking so long.
Also consider using SwingWorkers rather than constructing a new thread yourself. That could save you a few cycles of thread-startup time in the EDT.
Upvotes: 3