Task Queue for Heavy Weight Tasks in JavaSE Applications

Modern hardware systems have a multi-core architecture. So in contemporary software development concurrency is an even more crucial ingredient than before. But as we will see it is of great importance for single core systems, too. If you have already created a Java Swing application you’ve propably made an acquaintance with the SwingWorker, in order to delegate long running tasks from within Swing events to another thread. But first things first. In Swing the whole painting and event handling of the graphical user interface is executed in one thread the so called event dispatching-thread from AWT the underlying former window toolkit from Java. Therefore most of Swing-based methods are not thread-safe, meaning that you have to prevent race conditions by yourself, but it offers the possibility to dispatch tasks to the event-dispatcher thread. It is highly recommended to do everything, that updates the GUI in the corresponding thread.

This works as follows. The event dispatcher maintains a queue in which all UI-Events and external runnables, submitted via SwingUtilities#invokeLater() or SwingUtilities#invokeAndWait(), are enqueued and executes them one by one:
The Event Dispatching Queue

If you have a long-running task, like searching a file on the hard drive, being invoked by an event, e.g., a button click, you should not do this in the event-handling code, since you would block the whole queue until the task is finished leading to an unresponsive GUI experience. This is also true for single-core machines. Lets take a look at this. Imagine you have a machine with one core and you are executing a task like mentioned before. If you are doing this in the queue, you won’t be able to cancel the task or to do anything on the GUI. It will freeze. But good GUIs don’t freeze, even on single-core machines. Why is that? If you dispatch this task to another thread and w.l.o.g it iterates through a big loop, then you may call Thread#yield() in every iteration, in order to give the Java VM a hint that it can suspend this thread and give some calculation capacity to the GUI thread. In addition if it waits for example for an I/O-operation, the GUI thread can process some GUI events. Since Java is preemptive (on most machine/operating system combinations), it can (even without ‘yield’-hints) interrupt the external thread at any time, in order to give the dispatcher thread some time and vice versa. So this is (on single-core machines) not real concurrency, but it allows both threads to work alternatingly, which appears to be concurrent. This especially applies for multi-core machines. Furthermore the external task can check for Thread#isInterrupted() or if it waits, e.g., for interruptable I/O operations it can react to cancel-events of the user and terminate the execution prematurely. Here is a code example:

while(!finished) {
  if(Thread.interrupted()) {
    cleanup();
    return;
  }
  doStuff();
  Thread.yield();
}

It is of fundamental significance, that you program long-running tasks this way. If you counteract, you provoke tasks that cannot be canceled, leading to annoying system behavior. The tenet reads: The longer the task, the more eager it should be to react to cancellation.

Analogous to dispatching external execution to the swing thread by enqueuing it, long-running tasks should be send to external threads. For this purpose the Swing Worker has been developed and since Java 5 it is an integral part of the JRE and evolved in Java 6. With the SwingWorker you can execute a task in another thread and relieve the event dispatcher. In the early versions of the Swing Worker it started new threads for every execution and had no support for getting intermediate progress from it conveniently and show it, e.g., in a progress bar. So I implemented a second queue for executing long-running tasks on an external thread for Java 1.4.2. Lateron I refined it by using the ExecutorService of Java 5. Now in Java 6, the Swing Worker uses an ExecutorService by itself with a fixed number of worker threads and offers very convenient features for updating the GUI with progress and canceling an execution.

Was it worth implementing my own heavy weight task executor? Yes! Since the SwingWorker starts a fixed number of worker threads, that cannot be configured there might arise race conditions between the data structures and resources accessed in the external tasks. If you are a fan of the one-thread-philosophy of Swing, because it naturally serializes/sequentializes the access to the resources you may use a second queue for these tasks and exchange tasks between the GUI thread and the external thread. In this sense, long-running tasks are sent to the heavy weight task executor and GUI updates — like progress updates — are sent back.

How this can be achieved will be the topic of another post (as usual with a running code example for a rudimentary heavy weight task executor).

Posted in Java, Knowledge. Tags: , , . No Comments »

Exception Handling for Injection Interceptor

Remember my post “Circular Injection of Util Classes in EJB 3.0“? There I offered a some kind of ugly solution to the circular dependency problem for managed classes in Java EE 5. In a preceding post (Circular Dependencies of Session Beans) I grumbled about the exception handling in jBoss-5.1. It lets you alone with a meaningless error message and you have to guess what the problem is. Unfortunately my own code presented in the former post is even worse, since it logs problems but ignores them. It wasn’t mentioned for productive use, but it was annoying to me, so here is a little tune up adding exception handling and readable error messages.
(more…)

Inject CDI beans into Tapestry-5.x e.g. in Jboss-7.0.2-Final

As I explained in “Inject Java EE Beans into Tapestry-5.x“, the AppModule offers a way to configure Tapestry Web Applications directly in Java. In that post, we injected Java EE Beans into Tapestry applications. This time we do the same with Context and Dependency Injection (CDI) Beans. It follows the same procedure. The only difference is the way of looking up a bean. We still use JNDI for a lookup, but this time we retrieve the CDI BeanManager. In a second step we get the bean. For performance reasons we retrieve the bean only once per Thread (see annotation @Scope). It will be cached for subsequent lookups.
(more…)

CDI and Transactions e.g. in JBoss-7.0.2

In Java EE applications you are safe to consider that every method in a session bean has an associated transaction, since there is an implicit declaration of the transaction attribute required. If you like to change this behavior you have to configure this proactively by adding the annotation @TransactionAttribute with another value (see enum TransactionAttributeType). Context and Dependency Injection (CDI) does not have such an implicit declaration and no direct container managed support for transactions. But it has a very nice realization of the interceptor concept. This post shows, how to facilitate an interceptor in order to add a transaction to every (or a selection) method in a CDI bean, if it does not already exist. This is the default behavior of required.
(more…)

Circumvent Nested Transaction Issues in Tapestry-5.x

Ajax component events may be wrapped in a transaction as I pointed out in “Transaction Handling for Ajax Components in Tapestry-5.x“. But on some occasions an Ajax component event is surrounded by a component event. So the code in the ControllerUtil of article “Transaction Handling in Tapestry5” will lead to ‘transaction already active’ problems, since we try to begin a transaction in the nested ajax component event although there is already an active transaction attached to the current thread. We can overcome this situation by checking, whether an active transaction is present and begin/commit/rollback a new transaction iff not. This behavior is similar to the default transaction attribute REQUIRED in Java EE.
(more…)

Transaction Handling for Ajax Components in Tapestry-5.x

In “Transaction Handling in Tapestry5” I described, how to configure transactions wrapping a complete page or component render request. The same is necessary (possible) for Ajax components. Besides having less transactions and sharing the first-level-cache for subsequent calls, this realizes the “Open Session in View Pattern” automatically. So you can access the database lazily via getter from an entity, for example, without running into lazy loading exceptions due to the fact that the transaction has been closed and the entities are detached already.
(more…)

Inject Java EE Beans into Tapestry-5.x

Tapestry uses it’s own Inversion Of Control (IOC) container. Tapestry pages are not Servlets or Servlet Filter (and not another managed class). Therefore they cannot be used for injection of Java EE Beans. But there is the AppModule, which is conceptual some kind of related to Spring Java Config. It allows to configure the Tapestry application directly in Java. Like everything in Tapestry it has an Adaptive API. Hence you have to follow a naming (signature) pattern for your methods and Tapestry finds them. You don’t have to implement an interface.
(more…)

Tapestry-5.3.1 and Jboss-7.0.2-Final

The Java web framework Tapestry 5 has a hot deployment/reload feature, that traverses the classpath, looking for new resources to load. Unfortunately, it is not capable to parse URLs of Jboss’ virtual file system and therefore does not find it’s own core libraries. This issue has been tracked in TAP5-576 and a solution for Jboss-5 and Jboss-6 can be found in the corresponding wiki articles. The same problem remains for Jboss-7. Accidentally the reflective calls to virtual file are restricted. But the solution for Jboss-6.1 does still work. Here is a little tutorial how to achieve this.
(more…)

Posted in Java, Tutorials. Tags: , . No Comments »

Concurrent conversion of SVG to formats like PNG, EPS or PDF

In this post I’ll show how to use the ExecutorService of the java.concurrent package, in order to start as many inkscape shells as processors available on the current machine and to distribute a whole bunch of conversion tasks wisely on the cores. On my quad core I got a speedup of about 3.5, which is really near to 4.
(more…)

Informative Exceptions with Java Proxies

Information is essential for reasonable exception handling. Unfortunately, it is not always affordable to write custom exceptions providing all necessary information, especially in test code, e.g. for selenium tests. So, here is an approach to weave informative exceptions into your [test] code.
(more…)

Switch to our mobile site