Hang in Java FileSystemView getFileSystemView() getSystemIcon()
Wednesday, March 18th, 2009Recently I was working on a deadlock in our startup code.
It took some time to track it down as it never appeared as a deadlock (via CTRL-Break) it just stopped running with 0 CPU usage.
The cause was
FileSystemView.getFileSystemView().getSystemIcon(file)
It appears that this call fails when called from multiple threads asking for the same system icon.
Below is an example on how to show the issue. Its was tested with Java 1.6.0_07
public void testGetSystemIcon() throws IOException,
InterruptedException {
final FileImageThread t1 = new FileImageThread(".jpg");
final FileImageThread t2 = new FileImageThread(".jpg");
t1.start();
t2.start();
t1.join();
t2.join();
}
public class FileImageThread extends Thread {
final File file;
public FileImageThread(final String suffix) throws IOException {
file = File.createTempFile("test", suffix);
}
@Override
public void run() {
FileSystemView.getFileSystemView().getSystemIcon(file);
}
}
It does not hang every time, but it happens enough to be an issue.
The hang call stack is
Thread id=22 name=Thread-4 inState=WAITING deadlocked=false isNative=false sun.misc.Unsafe.park(Native Method) java.util.concurrent.locks.LockSupport.park(LockSupport.java:158) java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747) java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:905) java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1217) java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:218) java.util.concurrent.FutureTask.get(FutureTask.java:83) sun.awt.shell.Win32ShellFolderManager2$ComInvoker.invoke(Win32ShellFolderManager2.java:495) sun.awt.shell.Win32ShellFolder2.(Win32ShellFolder2.java:225) sun.awt.shell.Win32ShellFolderManager2.getDrives(Win32ShellFolderManager2.java:101) sun.awt.shell.Win32ShellFolderManager2.isFileSystemRoot(Win32ShellFolderManager2.java:323) sun.awt.shell.ShellFolder.isFileSystemRoot(ShellFolder.java:234) javax.swing.filechooser.FileSystemView.isFileSystemRoot(FileSystemView.java:310) com.osm.ui.FileImageUtilsTest$FileImageThread.run(FileImageUtilsTest.java:62) Thread id=21 name=Thread-3 inState=WAITING deadlocked=false isNative=false sun.misc.Unsafe.park(Native Method) java.util.concurrent.locks.LockSupport.park(LockSupport.java:158) java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747) java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:905) java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1217) java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:218) java.util.concurrent.FutureTask.get(FutureTask.java:83) sun.awt.shell.Win32ShellFolderManager2$ComInvoker.invoke(Win32ShellFolderManager2.java:495) sun.awt.shell.Win32ShellFolder2.(Win32ShellFolder2.java:225) sun.awt.shell.Win32ShellFolderManager2.getDrives(Win32ShellFolderManager2.java:101) sun.awt.shell.Win32ShellFolderManager2.isFileSystemRoot(Win32ShellFolderManager2.java:323) sun.awt.shell.ShellFolder.isFileSystemRoot(ShellFolder.java:234) javax.swing.filechooser.FileSystemView.isFileSystemRoot(FileSystemView.java:310) com.osm.ui.FileImageUtilsTest$FileImageThread.run(FileImageUtilsTest.java:62)
No one else seemed to see this issue, but I saw it lots of times on my PC.