Почему 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) {
Вы сделали две синхронизации подряд:
doSomething()
- Нить в
doSomething()