3

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?

Zeemee
  • 10,486
  • 14
  • 51
  • 81
  • 1
    Actually, I don't see the behaviour you describe. Thread A and B die instantly. One of Thread-X will wait on the other one as expected, but I don't see either Thread A or B waiting for any Thread-X – Guillaume Polet Apr 30 '12 at 06:22
  • Hi Guillaume, thank you for reading my question completely. Yes you're right - after I executed my example code as it is, it works as expected. Please see my updates. – Zeemee Apr 30 '12 at 06:39
  • Ok, I will update it, just a second. – Zeemee Apr 30 '12 at 06:42
  • Sorry guys, it seems to be a Webservice specific issue. this works in a plain java console application, but not in a web container. – Zeemee Apr 30 '12 at 06:50
  • 1
    There must be something else that your sample code does not reveal. If you start a new Thread, do you wait for it to return or this is asynchronous and you return immediately? – Guillaume Polet Apr 30 '12 at 06:58
  • Oh, saw a difference: The method itself is synchronized too. Could this be the reason? Does that synchronize with ClassA.this as lock object? – Zeemee Apr 30 '12 at 07:04
  • Why do you synchronize doSomething? I would really remove that as it prevents multi-threading to handle your requests. Yes, when you synchronize a method, it uses the instance as the lock (or on the class if the method is static) – Guillaume Polet Apr 30 '12 at 07:05
  • THAT'S IT! Do you create an answer for this? Would be glad to give you an "accept"... :) – Zeemee Apr 30 '12 at 07:08

4 Answers4

1

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

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • Thanks Guillaume, you already helped a lot. Could you provide a simple example for correctly using such a ThreadPool? – Zeemee Apr 30 '12 at 07:11
0

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

what do you want to synchronize?

Hachi
  • 3,237
  • 1
  • 21
  • 29
  • -1 because you repeat something that is obviously and ask something that would have been better asked as a comment. – Zeemee May 02 '12 at 13:44
0

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) {
GingerHead
  • 8,130
  • 15
  • 59
  • 93
0

You have done two synchronizations in a row:

  1. doSomething()
  2. The thread in doSomething()
GingerHead
  • 8,130
  • 15
  • 59
  • 93