More First Class Methods Code
I'm still experimenting with the prototype implementation of the FCM closures proposal. Here are a few utility methods that immediately came to mind.
withLock --
This one I've seen an example of online a few times. It automatically
release the lock when the block of code finishes executing.
public static void withLock(Lock lock, Runnable task) {
lock.lock();
try {
task.run();
} catch (Exception e) {
throw e;
} finally {
lock.unlock();
}
}
Example Usage:final ReentrantLock lock = new ReentrantLock();Now I'm not too fond of unchecked Exceptions, but rethrowing is still better then swallowing every exception that escapes the Runnable. Here is my second attempt.
withLock(lock, #{
// call some important locked code
});
private static interface ExceptionHandler {
public void uncaughtException(Runnable source, Throwable e);
}
public static void withLock(Lock lock, Runnable task, ExceptionHandler eHandel) {
lock.lock();
try {
task.run();
} catch (Exception e) {
eHandel.uncaughtException(task, e);
} finally {
lock.unlock();
}
}Example Usage:withLock(lock, #{
// do some code that needs to be locked.
// throw an exception to test the event handler.
throw new RuntimeException("year is even error");
}, #(Runnable source, Throwable e){
// inline implemented event handler.
e.printStackTrace();
}
);
Once
side effect of this is now one might be able to write reusable
exception handling code. There have been plenty of times where a method
I'm executing throws an exception, but there is no real way for me to
recover. All I can do is log the failure and continue on. I end up
writing the same try catch block over and over. It would be nice to
write something like this once and reuse it. public class LogAndContinueExceptionHandler implements ExceptionHandler{
public void uncaughtException(Runnable source, final Throwable e) {
SwingUtilities.invokeLater(#{
Logger.getLogger("ErrorLogger").log(Level.SEVERE, e.getMessage(), e);
});
}
}Example Usage:withLock(lock, #{
// do some code that needs to be locked.
// throw an exception to test the event handler.
throw new RuntimeException("year is even error");
}, new LogAndContinueExceptionHandler());
I used this idea when exploring another area that might benefit from closures. The EDT thread scheduling methods.invokeAndWait
public static void invokeAndWait(Runnable r, ExceptionHandler eHandel){
try {
SwingUtilities.invokeAndWait(r);
catch (InterruptedException e) {
eHandel.uncaughtException(e);
} catch (InvocationTargetException e) {
eHandel.uncaughtException(r, e.getCause());
}
}
public class AlertAndContinueExceptionHandler implements ExceptionHandler{
public void uncaughtException(Runnable source, final Throwable e) {
Runnable showMessageBox = #{
JOptionPane.showMessageDialog(null, e.getMessage());
};
if(SwingUtilities.isEventDispatchThread()){
showMessageBox.run();
}else{
SwingUtilities.invokeLater(showMessageBox);
}
}
}Example Usage:invokeAndWait(#{
JOptionPane.showMessageDialog(null, "Hello World");
}, new AlertAndContinueExceptionHandler());simpleSwingWorker
-- The simpleSwingWorker method is an attempt to apply closures to the
simple case of, "do something off the EDT then do something ON the EDT".public static void simpleWorker(final Runnable offEDT, final Runnable onEDT){
Thread bGround = new Thread(#{
offEDT.run();
SwingUtilities.invokeLater(onEDT);
});
bGround.start();
}
Example Usage:simpleWorker(#{
System.out.println("sleep");
Thread.currentThread().sleep(1000);
System.out.println("start");
}, #{
JOptionPane.showMessageDialog(null, "Hello World");
});I also wrote a blocking version based on invokeAndWait. public static void simpleBlockingWorker(final Runnable offEDT, final Runnable onEDT){
Thread bGround = new Thread(#{
offEDT.run();
SwingUtilities.invokeAndWait(onEDT);
});
bGround.start();
}Hay wait a second, invokeAndWait throws exceptions right? And yet the code as it stands compiles without issue. I think I may have found a bug in the FCM prototype.
Some may look at these examples and point out that this type of functionality may really fall into the realm of "control structures". There is some debate in the Java community as to weather the common man should be allowed to write their own control structures. Some prefer to leave this responsibility with the language designers. It is my opinion that once you make this type of code easy, then you already have allowed the common man to make their own control structures. In that case you might as well legitimize the pattern and provide as much support as is possible.
I look forward to the day when there is a Java Control Abstraction (JCA) prototype to play around with.
Collin Fagan is a software engineering contractor located in the Chicago suburbs. He holds a BS in Computer Science from the Rochester Institute of Technology. Collin has worked in the Medical, Produce Warehousing and Telecommunications industries on a wide assortment of projects ranging from customized Linux thin clients to highly concurrent telecommunications control systems. His favorite language is Java and devotes much of his blogging time to Swing and Java2D. Collin is a DZone MVB and is not an employee of DZone and has posted 9 posts at DZone.
- Login or register to post comments
- 3016 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
Stefan Schulz replied on Tue, 2008/03/11 - 5:51pm
It's cool to see some FCM code. Of course, the prototype is not perfect, and you should have recognized right in your first example, what you noticed in your final one ;)
One thing, though: the JCA would not allow you to do EDT stuff, as it uses unrestricted blocks (allowing for break, return and continue). In our view it would obscure the control flow, as it presents as being executed immediately while passing anonymous methods visually hands over a block of code.
Nice examples, though, which made me jealous when still using Java5 at work. ;)
cfagan replied on Tue, 2008/03/11 - 6:36pm