Say you have a standalone (non-web) application where you want to show images. Suppose the images don't have dependencies among each other, so you can load and show each image in a separate thread.
Now say you want to design the same thing as a web application. To make things more concrete, suppose you want to build an application that shows a map of a region as a set (matrix) of tiles, each tile being displayed in a certain, predetermined part of the viewer. Let's call this application randomly 'google maps'.
So we'll have a servlet - say we build this with Java technology - that talks to a certain service from which it gets the corresponding tiles and then generates the page showing these tiles in their proper positions. It is tempting to take the same approach as in the standalone application and let the servlet run threads, each of them dealing with a tile. However, we know running threads from servlets calls for trouble (I'll write about that in separate posts).
So, what to do ? Well, the idea is to run the requests for the tiles in parallel as Ajax requests from - for example, a JavaScript piece of code residing in a JSP page. Each such Ajax request invokes the servlet to retrieve the desired tile. Thus, the servlet remains "pure", unpolluted with dangerous threads and we leave the parallelism and all the other optimizations in the hands of the web container.
Showing posts with label multithreading. Show all posts
Showing posts with label multithreading. Show all posts
Thursday, December 9, 2010
Sunday, June 27, 2010
Invoke code on a certain thread in C# / .NET
Virtually all GUI frameworks and the languages that come with them give you the possibility to invoke a certain piece of code on the UI thread. This is necessary because the UI components aren't usually thread safe (making all their methods thread safe would be a big blow to the performance of the application), so any update of the UI can't be done from another thread. That piece of code needs to be marshalled to the main thread.
.NET goes a step further and offers us the possibility to invoke a piece of code on any thread. The example bellow shows how this can be done.
ThreadTask will be run in a new thread, whose name is "Alpha thread". We create a Control on this thread (new Control()) and then we create its handle: ctrl.CreateControl().
Finally, we do Application.Run(), which makes our thread wait for messages in the message loop.
Then we use our control to invoke the method MyTestMethod on our thread.
Note that control handle creation is essential; without it, MyTestMethod would be invoked on the main thread. Also, attaching the thread to the message loop by doing Application.Run() ensures that the thread waits for invokes from other threads.
Check out here how to do the same thing in Java.
.NET goes a step further and offers us the possibility to invoke a piece of code on any thread. The example bellow shows how this can be done.
ThreadTask will be run in a new thread, whose name is "Alpha thread". We create a Control on this thread (new Control()) and then we create its handle: ctrl.CreateControl().
Finally, we do Application.Run(), which makes our thread wait for messages in the message loop.
Then we use our control to invoke the method MyTestMethod on our thread.
Note that control handle creation is essential; without it, MyTestMethod would be invoked on the main thread. Also, attaching the thread to the message loop by doing Application.Run() ensures that the thread waits for invokes from other threads.
using System;
using System.Windows.Forms;
using System.Threading;
namespace TestThreads2 {
public class TestThread {
private Control ctrl = null;
// This method that will be called when the thread
// is started
public void ThreadTask() {
if (ctrl == null) {
// create the control
ctrl = new Control();
// create the handle
ctrl.CreateControl();
}
Console.WriteLine("ThreadTask is running on thread: " +
Thread.CurrentThread.Name);
// ensure the message loop is attached to this thread
Application.Run();
}
public Control Ctrl {
get { return ctrl; }
set { ctrl = value; }
}
}
public class Program {
private static void MyTestMethod() {
Console.WriteLine("TestMethod invoked on thread: " +
Thread.CurrentThread.Name);
}
static void Main(string[] args) {
//Control.CheckForIllegalCrossThreadCalls = true;
TestThread myThread = new TestThread();
Thread thread =
new Thread(
new ThreadStart(myThread.ThreadTask)
);
thread.Name = "Alpha thread";
thread.Start();
Thread.Sleep(1000);
if (myThread.Ctrl.InvokeRequired) {
myThread.Ctrl.BeginInvoke(
new MethodInvoker(MyTestMethod)
);
} else {
MyTestMethod();
}
}
}
}Check out here how to do the same thing in Java.
Labels:
.net,
c#,
multithreading
Saturday, June 19, 2010
Invoke code on a certain thread in Java
I think Java should be a bit jealous on the .NET's interesting feature of being able to invoke a piece of code on any given thread. In .NET that's possible by creating a Control (say myControl) on a certain thread and then using myControl.Invoke or myControl.BeginInvoke having as parameter the piece of code you want to invoke on that thread. The parameter is a delegate, another feature missing in Java, but let's ignore this for now.
In Java we have SwingUtilities.invokeAndWait and SwingUtilities.invokeLater to invoke code on the event dispatching thread, but not on any given thread. They take a Runnable as parameter.
So how would we implement such a feature in Java ? We'll need a thread that has nothing better to do but try to dequeue items from its queue and invoke them (the items would be the pieces of code that we need invoked on that thread). Something like this:
And the actual thread (I simulate the .NET delegate by using Java anonymous classes):
We need an interface for our task - either an existing one (Swing uses Runnable), or a new one, like:
Finally, the test class with the main method:
It should come as no surprise the output:
main thread: 1 main
perform task on thread: 7 Thread-0
perform task again on thread: 7 Thread-0
In Java we have SwingUtilities.invokeAndWait and SwingUtilities.invokeLater to invoke code on the event dispatching thread, but not on any given thread. They take a Runnable as parameter.
So how would we implement such a feature in Java ? We'll need a thread that has nothing better to do but try to dequeue items from its queue and invoke them (the items would be the pieces of code that we need invoked on that thread). Something like this:
package threading;import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Invoker { private static Thread myThread; private static BlockingQueue<Task> queue; private Invoker() { } public static void BeginInvoke(Task task) { if (myThread == null) { queue = new LinkedBlockingQueue<Task>(); myThread = new MyThread(queue); myThread.start(); } if (Thread.currentThread() != myThread) { try { queue.put(task); } catch(InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupt(); } } else { task.perform(); } } }
And the actual thread (I simulate the .NET delegate by using Java anonymous classes):
package threading; import java.util.concurrent.BlockingQueue; public class MyThread extends Thread { private final BlockingQueue<Task> taskQueue; public MyThread(BlockingQueue<Task> queue) { taskQueue = queue; } public void run() { while(true) { try { Task currentTask = taskQueue.take(); currentTask.perform(); } catch (InterruptedException e) { e.printStackTrace(); // Restore the interrupted status Thread.currentThread().interrupt(); } } } }
We need an interface for our task - either an existing one (Swing uses Runnable), or a new one, like:
package threading;public interface Task { void perform(); }
Finally, the test class with the main method:
package threading; public class Test { public static void main(String[] args) { System.out.println("main thread: " + Thread.currentThread().getId() + " " + Thread.currentThread().getName()); Invoker.BeginInvoke(new Task() { public void perform() { System.out.println("perform task on thread: " + Thread.currentThread().getId() + " " + Thread.currentThread().getName()); } }); Invoker.BeginInvoke(new Task() { public void perform() { System.out.println("perform task again on thread: " + Thread.currentThread().getId() + " " + Thread.currentThread().getName()); } }); } }
It should come as no surprise the output:
main thread: 1 main
perform task on thread: 7 Thread-0
perform task again on thread: 7 Thread-0
Labels:
Java,
multithreading
Subscribe to:
Posts (Atom)