Take the 2-minute tour ×

I already read the great article about Servlet Thread handling.

I have the following problem: I want to create a simple Servlet that starts either a new Thread that produces in a first version random messages or - depending on the parameter - send a response with all messages that were produced since last request.

I use JQuery AJAX call on browser-site an handled requests with timeouts.

When I run my receiver calls, I get only the first messages that were produced since the thread crashed in the meanwhile. It looks as it would be a thread-safety problem, described in the above-mentioned article, but I can figure it out exactly. The log gives me the following information:

SEVERE: Exception in thread "Thread-75" 
SEVERE: java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at com.lancom.lsr.util.RandomMessageProducer.run(RandomMessageProducer.java:35)
    at java.lang.Thread.run(Thread.java:722)

SEVERE:     at java.lang.Object.wait(Native Method)
SEVERE:     at com.lancom.lsr.util.RandomMessageProducer.run(RandomMessageProducer.java:35)
SEVERE:     at java.lang.Thread.run(Thread.java:722)

This is my current servlet code:

public class MyServlet extends HttpServlet { 
private RandomMessageProducer rmProducer;
private Thread rmpThread; 

    Map<Integer, String> msg = new HashMap<Integer, String>();
    Gson gson = new Gson();

    String sDevs   = request.getParameter("devices");  // Option 1
    String sGetMsg = request.getParameter("rec_msg"); // Option 2
    PrintWriter pw = response.getWriter();

    // Request: Send information and run thread
    if (sDevs != null && STATUS==0) {                       

       /* Start a dummy producer */             
       rmProducer = new RandomMessageProducer();
       rmpThread = new Thread( rmProducer )

       pw.print("{\"1\": \"Action started!\"}");
       //  Request: Receive messages
    else if (sGetMsg != null) {
       List<String> logs = rmProducer.getLogMsg();      
       for (String lmsg : logs) {
            // Check if we can update the current Status
           if (msg.equals("<<<FIN_SUCC>>>") || msg.equals("<<<FIN_ERR>>>")) {
           msg.put(0, lmsg);
       String json = gson.toJson(msg);      

And this is my simple message-producer thread:

public class RandomMessageProducer implements Runnable {

    private Queue<String> msgQueue = new LinkedList<String>();

    public void run() {
        Random randomGenerator = new Random();
        for (int idx = 1; idx <= 100; ++idx){
          int randomInt = randomGenerator.nextInt(100);
          msgQueue.add("Generated : " + randomInt);
          try {
          } catch (InterruptedException e) {

    public List<String> getLogMsg() {
        List<String> res = new ArrayList<String>();
        while (!msgQueue.isEmpty()) {
            res.add( msgQueue.poll() );
        return res;

The requests are performed all 1000ms

Do you probably see my error in reasoning?

Thanks a lot!

share|improve this question
what is line 35 in RandomMessageProducer? –  Elior Apr 22 '13 at 10:54
add comment

1 Answer

up vote 2 down vote accepted

You have serious thread-safety issues here.

First of all, you're using wait() when all you want to do is sleep for a few milliseconds. You should use Thread.sleep() instead. That will solve your exception, but won't solve the thread-safety issues.

You have a shared linked list that is used by multiple threads in parallel : the random generator thread stors messages in the queue whild the servlet thread(s) emoved messages from the queue. You should thus either use a concurrent collection (like a ConcurrentLinkedQueue), or synchronize every access to the linked list. I would use a Concurrent collection.

And finally, several servlet threads read and modify the rmpThread and rmProducer variables in parallel, without any kind of synchronization. The rmpThread variable is written, but never read, so I would make it a local variable instead. To make sure the newly written rmProducer is visible by the other servlets, you need to synchronize all its accesses, either by using a synchronized block to write and read it, or by making it volatile, or by wrapping it into an AtomicReferece (that's the choice I would make).

So the rmProducer should be declared like this:

private AtomicReference<RandomMessageProducer> rmProducerRef = new AtomicReference<>();

To modify its value, you should use


And to get it, you shuld use

share|improve this answer
Well, I see I have to concern myself with valid thread handling. Thanks for your detailed description! –  John Rumpel Apr 23 '13 at 10:41
add comment

Your Answer


