The post() method consumes plain-text data. The first thing we do is store a UriBuilder in
a local variable of the base URI of our service. We then queue up a task for our writer thread.
We cannot use the UriInfo member variable in this background task. The CustomerChat
class is a singleton and can accept requests concurrently. Because of this, the UriInfo ur-
iInfo member variable is a proxy that delegates to the request's actual UriInfo by using an
underlying ThreadLocal in most JAX-RS vendor implementations. If the writer background
thread invokes on this proxy, it would get an error because ThreadLocal data is not trans-
ferred between different threads.
writer . submit ( new
new Runnable ());
void run ()
synchronized ( messages )
Message message = new
new Message ();
message . id = Long . toString ( counter . incrementAndGet ());
message . message = text ;
Each new message post is queued up for the writer thread in an implementation of the Run-
nable interface. This task starts off by synchronizing on the messages variable. This pro-
tects the critical parts of our message service by serializing access to the messages map. The
code then creates a Message instance using an id generated from the counter .
iif ( messages . size () == 0 )
first = message ;
last . next = message ;
The writer thread next checks to see if this is the initial message to the system. If so, it sets
the first member variable to point to the first message posted to the service. Otherwise, it
points the tail of the Message linked list to this new Message instance.
messages . put ( message . id , message );
last = message ;
The code then stores the new message in the messages map and sets the last member vari-
able to point to this new message.