Question

Please see my code example of a JAX-WS Webservice:

@WebService
public class ClassA {

@WebMethod
public synchronized void doSomething() {
    new Thread(new Runnable() { // Thread X
        @Override
        public void run() {
            synchronized (ClassA.this) {
                // Do something which should be run in this separate
                // thread, but not twice at the same time
                try {
                    System.out.println("Thread X Start");
                    Thread.sleep(10000);
                    System.out.println("Thread X End");
                } catch (InterruptedException e) {
                }
            }
        }
    }).start();
}

}

If the WebMethod is called twice, the second call is waiting for thread X to complete - why?

Was it helpful?

Solution

The problem is that you have synchronized also doSomething. This should definitely be removed as it prevents multi-threading in your webservice. For the inner synchronized block, I would also remove it and try to use a single-Thread ThreadPool so that the jobs are executed one at a time.

    // Initiate you thread pool and make sure it is unique
    ExecutorService service = Executors.newFixedThreadPool(1);

    ...
    // In your web method:
    Future<?> futureResult = service.submit(new Runnable()/or new Callable());
    // Using callable, you will get a Typed Future

    Object result = futureResult.get();// If you need to wait for the result of the runnable/callable.
    ...

This is available since Java 1.5

OTHER TIPS

seams like both threads synchronize on the instance of ClassA (ClassA.this)

what do you want to synchronize?

For some reasons, Thread B is waiting for Thread A-X (X originated by A) to be
finished - any idea why? I expected that only B-X (X originated by B) is waiting for the lock.

After this code part is executed in method webRequests:

new Thread(new Runnable() { // Thread A
             doSomething();
         }).start();

The instruction is expected most likely to continue with the second part of the method:

new Thread(new Runnable() { // Thread B
             doSomething();
         }).start();

But it will not whatsoever. WHY?:

BECAUSE the main thread which is executing the code can't access the object code anymore, even the above remaining part of the method. because access is denied on this object because of:

synchronized(ClassA.this) {

You have done two synchronizations in a row:

  1. doSomething()
  2. The thread in doSomething()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top