Почему WebMethods блокируются, когда потоки синхронизируются?

Пожалуйста, посмотрите мой пример кода веб-службы JAX-WS:

@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();
}

}

Если WebMethod вызывается дважды, второй вызов ожидает завершения потока X - почему?

4 ответа

Решение

Проблема в том, что вы синхронизируете и делаете что-то. Это определенно следует удалить, поскольку это предотвращает многопоточность в вашем веб-сервисе. Для внутреннего синхронизированного блока я бы также удалил его и попытался использовать однопотоковый ThreadPool, чтобы задания выполнялись по одному за раз.

    // 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.
    ...

Это доступно начиная с Java 1.5

Швы, как оба потока синхронизируются в экземпляре ClassA (ClassA.this)

что вы хотите синхронизировать?

По некоторым причинам поток B ожидает, пока поток AX (X возник из A)
закончил - есть идеи почему? Я ожидал, что только BX (X, созданный B) ожидает блокировки.

После этого часть кода выполняется в методе webRequests:

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

Ожидается, что инструкция, скорее всего, продолжится со второй части метода:

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

Но это не будет вообще. ЗАЧЕМ?:

ПОТОМУ ЧТО основной поток, выполняющий код, больше не может получить доступ к объектному коду, даже вышеупомянутой оставшейся части метода. потому что доступ к этому объекту запрещен из-за:

synchronized(ClassA.this) {

Вы сделали две синхронизации подряд:

  1. doSomething()
  2. Нить в doSomething()
Другие вопросы по тегам