Java 为什么同步线程时阻止WebMethods?

Java 为什么同步线程时阻止WebMethods?,java,multithreading,web-services,jax-ws,synchronized-block,Java,Multithreading,Web Services,Jax Ws,Synchronized Block,请参阅我的JAX-WS Web服务代码示例: @WebService public class ClassA { @WebMethod public synchronized void doSomething() { new Thread(new Runnable() { // Thread X @Override public void run() { synchronized (ClassA.this) {

请参阅我的JAX-WS Web服务代码示例:

@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完成-为什么

两个线程在ClassA实例上同步(ClassA.this)

您想同步什么?

由于某些原因,线程B正在等待线程A-X(由A发起的X)被同步
完成-知道为什么吗?我以为只有B-X(X由B发起)在等待 为了锁

在方法
webRequests
中执行此代码部分后:

new Thread(new Runnable() { // Thread A
             doSomething();
         }).start();
该指令最有可能继续执行方法的第二部分:

new Thread(new Runnable() { // Thread B
             doSomething();
         }).start();
但无论如何都不会。为什么

因为执行代码的主线程不能再访问目标代码,即使是方法的上述剩余部分。因为以下原因拒绝对此对象的访问:

synchronized(ClassA.this) {

问题是您还同步了doSomething。这一定要删除,因为它会阻止Web服务中的多线程。对于内部的synchronized块,我还将删除它并尝试使用,以便一次执行一个作业

    // 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.
    ...
//启动线程池并确保它是唯一的
ExecutorService=Executors.newFixedThreadPool(1);
...
//在web方法中:
Future futureResult=service.submit(new Runnable()/或new Callable());
//使用callable,您将得到一个类型化的Future
Object result=futuresult.get();//如果需要等待runnable/callable的结果。
...

这是自Java 1.5以来可用的,您已经连续完成了两次同步:

  • doSomething()
  • doSomething()中的线程

  • 事实上,我没有看到你描述的行为。线A和线B立即消失。线程-X中的一个将按预期等待另一个,但我没有看到线程A或线程B等待任何线程XHi Guillaume,感谢您完整阅读我的问题。是的,你说得对-在我按原样执行示例代码之后,它就按预期工作了。请查看我的更新。好的,我会更新它,请稍候。对不起,伙计们,这似乎是一个特定于Web服务的问题。这可以在普通的java控制台应用程序中使用,但不能在web容器中使用。如果您启动一个新线程,是等待它返回,还是这是异步的,您会立即返回?谢谢Guillaume,您已经帮了很多忙了。你能提供一个简单的例子来正确使用这样一个线程池吗?-1因为你重复了一些明显是错误的东西,然后问了一些本可以作为评论的东西。