当线程同步时,为什么WebMethods会被阻止?

3
请查看我的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();
}

如果WebMethod被调用两次,第二个调用会等待线程X完成 - 为什么?

1
实际上,我没有看到你所描述的行为。线程A和B立即终止。Thread-X中的一个将按预期等待另一个,但我没有看到任何线程A或B等待任何Thread-X。 - Guillaume Polet
嗨Guillaume,感谢您完整阅读我的问题。是的,您是正确的 - 在我按照示例代码执行它后,它按预期工作。请查看我的更新。 - Zeemee
好的,我会更新它,稍等一下。 - Zeemee
抱歉,伙计们,这似乎是一个Web服务特定的问题。在普通的Java控制台应用程序中可以工作,但在Web容器中却不能。 - Zeemee
1
你的示例代码肯定还有其他操作。如果你启动了一个新线程,你是等待它返回结果还是异步执行并立即返回呢? - Guillaume Polet
显示剩余3条评论
4个回答

1
问题在于您还同步了doSomething。这绝对应该被删除,因为它会阻止您的Web服务进行多线程处理。对于内部同步块,我也会将其删除,并尝试使用单线程线程池,以便作业逐个执行。
    // 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版本开始可用


谢谢Guillaume,你已经帮了很多忙。你能提供一个简单的例子来正确使用ThreadPool吗? - Zeemee

0

由于某些原因,线程B正在等待线程A-X(X由A发起)完成 - 有什么想法吗?我原本以为只有B-X(X由B发起)在等待锁。

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

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

这个指令很可能会继续执行方法的第二部分:

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

但它根本不会。为什么?:

因为执行代码的主线程无法再访问对象代码,即使是方法上面剩余的部分也无法访问。因为由于以下原因,该对象被拒绝访问:

synchronized(ClassA.this) {

0

看起来两个线程都在 ClassA 的实例(ClassA.this)上同步。

你想要同步什么?


-1 是因为你重复了一些显而易见的内容,并且提出的问题最好作为评论来问。 - Zeemee

0

你已经连续进行了两次同步:

  1. doSomething()
  2. doSomething() 中的线程

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接