Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SunToolkit.awtLock: does code that takes such a lock needs to be called on the EDT

Tags:

java

swing

awt

I was investigating a deadlock and saw the following in the thread dump

at sun.awt.SunToolkit.awtLock(SunToolkit.java:229)
at sun.awt.X11.XRobotPeer.setup(Native Method)
- locked <0x00000000a633fbd0> (a java.lang.Class for sun.awt.X11.XRobotPeer)
at sun.awt.X11.XRobotPeer.<init>(XRobotPeer.java:24)
at sun.awt.X11.XToolkit.createRobot(XToolkit.java:683)
at java.awt.Robot.init(Robot.java:119)
at java.awt.Robot.<init>(Robot.java:77)

This is caused by calling Robot robot = new Robot();

This call takes a lock (SunToolkit.awtLock) and I was wondering who else is using that lock, and if it would be better if I moved that new Robot() call to the EDT. The name suggests that it is used by AWT which is single threaded. If something on the EDT takes this lock as well (e.g. a Swing component), my chances of hitting a deadlock increase when I create the Robot off the EDT.

On the other hand, as discussed in this question, a lot of the Robot methods are designed to throw an exception when called on the EDT. This would make it annoying if you would be best to create the Robot instance on the EDT.

The same problem exists for Toolkit.getDefaultToolkit().getScreenResolution() so no need to focus solely on the Robot class:

at sun.awt.SunToolkit.awtLock(SunToolkit.java:229)
at sun.awt.X11.XToolkit.getScreenResolution(XToolkit.java:999)

So what I am trying to clear up:

  • Who are the interested parties in that lock ?
  • Was that lock perhaps only introduced in an attempt to make Swing/AWT multi-threaded (or at least a bit more thread-safe), but would the recommended approach be to avoid taking that lock on another thread then the EDT ?
  • Is there any official Oracle/Sun documentation available (something like the Concurrency in Swing guide) which I can consult ? My Google skills failed me on this.
like image 516
Robin Avatar asked Apr 16 '13 11:04

Robin


1 Answers

See the source code for SunToolkit.java here: http://www.docjar.com/html/api/sun/awt/SunToolkit.java.html the purpose of the AWT_LOCK is explained on line 208.

Here's the excerpt in case the page disappears:

/** 
 * The AWT lock is typically only used on Unix platforms to synchronize
 * access to Xlib, OpenGL, etc.  However, these methods are implemented
 * in SunToolkit so that they can be called from shared code (e.g.
 * from the OGL pipeline) or from the X11 pipeline regardless of whether
 * XToolkit or MToolkit is currently in use.  There are native macros
 * (such as AWT_LOCK) defined in awt.h, so if the implementation of these
 * methods is changed, make sure it is compatible with the native macros.
 *   
 * Note: The following methods (awtLock(), awtUnlock(), etc) should be
 * used in place of: 
 *     synchronized (getAWTLock()) {
 *         ... 
 *     }   
 *   
 * By factoring these methods out specially, we are able to change the 
 * implementation of these methods (e.g. use more advanced locking
 * mechanisms) without impacting calling code.
 *   
 * Sample usage:
 *     private void doStuffWithXlib() {
 *         assert !SunToolkit.isAWTLockHeldByCurrentThread();
 *         SunToolkit.awtLock();
 *         try {
 *             ... 
 *             XlibWrapper.XDoStuff();
 *         } finally {
 *             SunToolkit.awtUnlock();
 *         }   
 *     }   
 */
like image 118
lyaffe Avatar answered Oct 19 '22 00:10

lyaffe