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) {Example Usage:
lock.lock();
try {
task.run();
} catch (Exception e) {
throw e;
} finally {
lock.unlock();
}
}
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 {Example Usage:
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();
}
}
withLock(lock, #{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.
// 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();
}
);
public class LogAndContinueExceptionHandler implements ExceptionHandler{Example Usage:
public void uncaughtException(Runnable source, final Throwable e) {
SwingUtilities.invokeLater(#{
Logger.getLogger("ErrorLogger").log(Level.SEVERE, e.getMessage(), e);
});
}
}
withLock(lock, #{I used this idea when exploring another area that might benefit from closures. The EDT thread scheduling methods.
// 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());
invokeAndWait
public static void invokeAndWait(Runnable r, ExceptionHandler eHandel){Example Usage:
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);
}
}
}
invokeAndWait(#{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".
JOptionPane.showMessageDialog(null, "Hello World");
}, new AlertAndContinueExceptionHandler());
public static void simpleWorker(final Runnable offEDT, final Runnable onEDT){Example Usage:
Thread bGround = new Thread(#{
offEDT.run();
SwingUtilities.invokeLater(onEDT);
});
bGround.start();
}
simpleWorker(#{I also wrote a blocking version based on invokeAndWait.
System.out.println("sleep");
Thread.currentThread().sleep(1000);
System.out.println("start");
}, #{
JOptionPane.showMessageDialog(null, "Hello World");
});
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 it possible.
I look forward to the day when there is a Java Control Abstraction (JCA) prototype to play around with.
3 comments:
The current FCM prototype does not handle exceptions well. At least it is in the release notes...
I guess I should have read them more carefully then, LOL. But it's no big deal anyways. I'm very impressed with how functional it is for a prototype.
Good for people to know.
Post a Comment