Monday, February 06, 2006

One Thread to rule them all

In UI Applications it is a requirement to run some tasks in different threads so that the user will not notice a lag while performing some operations. Also often these threads are either of not very long duration or need to be run one after the other. So how do we solve this?


A small diversion to Threads in Java

Now in Java the Runnable interface is used to create threads. Runnable contains a single method run() which needs to be implemented.

<code>
public class MyThread implements Runnable {
public void run() {
//do some task
}
}
</code>

To execute the above as a separate thread you need to call the start method of the Thread class. The Thread class can accept a Runnable instance

<code>
new Thread(new MyThread()).start()
</code>

start() internally performs some housekeeping to actually create the new thread. After performing the necessary operations, Runnable.run() is called.


Back to our UI Application.

What is done is a simple event queue is built for handling all non-ui tasks. Which internally contains a Queue and a single thread.

<code>
public class Worker implements Runnable {

private Queue queue;
private boolean running;

private Worker INSTANCE = new Worker();

private Worker() {
new Thread(this).start();
}

public static Worker getInstance() {
return INSTANCE;
}

public void run() {
if(!running) {
running = true;
while(true) {
if( queue.peek() ) {
Runnable runnable = queue.pop();
runnable.run();
}
}
}

public void addRunnable(Runnable runnable) {
queue.push(runnable);
}

}
</code>

I have just given a basic skeleton here and left out the most important part of synchronizing the class. The running boolean was added to prevent new Thread(Worker.getInstance()).start(). You guys see any more errors? Threads are one of my primary weaknesses which I hope to rectify by learning about the new Java 5 Concurrency features.


For small tasks it is more efficient to use a Worker like this which internally doesn't create a new Thread for each task and re-uses a Thread or even a thread pool. This is because the start() method does quite a bit internally.

In Swing it's suggested to use a SwingWorker class which does something similar. Also Java 5 (Tiger) has added a new SwingWorker class which is additionally Generic.

The generic question now. Have you guys come across any similar stuff in other languages? Java has had good support for threading since the early days and now in Java 5 this has been greatly enhanced. What about other languages? C++, C#. And anyone have info about dynamic languages like Lisp, Python etc?

1 comment:

Yang said...

Threading support in Python is very primitive, but (for apps that use threading primarily for I/O) Twisted-Python is a wonderful and expansive event-based async-I/O library.

Also check out Stackless Python (or Google for microthreads/tasklets for a more general taste).