来自多个线程的java调用函数未声明为线程安全

来自多个线程的java调用函数未声明为线程安全,java,multithreading,web-services,thread-safety,jax-ws,Java,Multithreading,Web Services,Thread Safety,Jax Ws,有一个JDK函数,尽管javadocs没有声明它是线程安全的,但是从Google中的代码来看,我似乎可以通过从多个线程调用它来获得我想要的结果,而不会产生不良的副作用,因为该函数主要使用堆栈变量。因此,它是否具有同步块并不重要。我想知道我是否错过了什么,最终遇到了麻烦。 函数是connection.call(requestMsg,url);从saajapi创建SOAPConnection。我应该如何分析它以决定是否从多个线程使用它 谢谢 一般规则是方法和类是线程安全的,除非另有说明。因此,例如R

有一个JDK函数,尽管javadocs没有声明它是线程安全的,但是从Google中的代码来看,我似乎可以通过从多个线程调用它来获得我想要的结果,而不会产生不良的副作用,因为该函数主要使用堆栈变量。因此,它是否具有同步块并不重要。我想知道我是否错过了什么,最终遇到了麻烦。 函数是connection.call(requestMsg,url);从saajapi创建SOAPConnection。我应该如何分析它以决定是否从多个线程使用它


谢谢

一般规则是方法和类是线程安全的,除非另有说明。因此,例如RMI方法是线程安全的,与此相同

Java平台API规范是调用方和实现之间的契约。

规范描述了调用方可以依赖的每个方法行为的所有方面。它没有描述实现细节,例如方法是本机的还是同步的。规范应(以文本形式)描述给定对象提供的线程安全保证。如果没有明确的相反指示,则假定所有对象都是“线程安全的”(即允许多个线程同时访问它们)。人们认识到,当前的规范并不总是符合这一理想

在我看来,理想情况下,您应该能够假设标准JavaAPI是线程安全的,除非另有说明。但最后一句话告诉我,假设这永远是真的,这是一件相当危险的事情。当然,对于大多数Swing API,您不应该假设线程安全

我认为以下是一种合理的方法来决定什么是线程安全的:

  • 如果javadoc明确表示某些东西是线程安全的,那么您可以相信它是线程安全的
  • 如果javadoc明确指出某些东西不是线程安全的,那么您可以相信它是非线程安全的
  • 如果javadoc什么也没说,并且仔细检查源代码后发现它是线程安全的,那么您可以相信它是线程安全的
  • 如果javadoc什么也没说,仔细检查源代码就会发现它不是线程安全的,那么所有的赌注都没有了。这可能是javadoc错误,也可能是当前实现的缺陷

(这是基于这样一种观察,即Sun/Oracle不太可能做出破坏向后兼容性的更改。更改标准API的线程安全特性可能会导致潜在的并发错误……因此,这种可能性加倍。)

我支持Stephen-如果它没有明确表示它是线程安全的,假设不是这样。
话虽如此,我查看了代码,经过大约15分钟的检查,代码看起来还可以

主要的问题是看线程之间是否存在任何共享变量,以及它们是否会受到两个或多个线程并发调用的影响。当然,这可能是一个漫长而棘手的过程,因为一个类可能由其他几个类组成,而这些类又由其他几个类组成


如果是我,我会重新构造我的代码,以确保我没有以多线程的方式调用,因为调试这将是一场噩梦,而且我不能保证它将在100%的时间内工作

这是你的决定:正如脏哈利曾经说过的:“你今天觉得幸运吗?你呢?”


另一方面,我回答了这个问题,答案也可能适用于此。

绝对不行。如果它没有被明确地记录为线程安全的,我们就不会假设它是线程安全的。不要介意Sun在Vector、Hashtable、StringBuffer、旧java内存模型和单处理器机器时代提出的建议。时尚已经转变。我们生活在一个截然不同的java并发世界中

对于一个可变类,它更可能是在编写时只考虑一个线程。所以我认为,如果没有doc,我们必须假设它是针对单线程的。外部同步必须用于更广泛的情况。(与更精细级别的锁定相比,这通常有助于提高性能)

对于实际设计用于多线程的类,它必须提供关于其行为的详细文档。把它简单地标记为“线程安全”是毫无意义的。有太多的事情需要解释和记录,请查看任何并发类

因此,假设“默认”线程安全模式是毫无意义的。这没有任何意义

--

对于您特定的查询,如果实现如下

constructor()
  open socket

Response call(Request)
  write request to socket output stream
  read response from socket input stream

close()
  close socket
如果没有调用同步(),这显然是不安全的。如果您在TCP连接上有并发读/写操作,则可以确保混乱


假设我写了一个更安全的实现,我会保持沉默吗?当然不是。我会告诉用户允许并发调用();每个请求都是以原子方式编写的;管道用于吞吐量;响应按请求的顺序返回;close()可以被任何线程随时调用;未完成的呼叫将有x秒时间优雅地完成;之后,连接被中止;任何等待call()的线程都将收到一份请柬。

谢谢您的回复。我以为恰恰相反。除非另有说明,否则jdk类不是线程安全的。你是说我可以从多个线程安全地调用这个函数,因为javadocs中没有关于线程安全的说明?你有关于这个“一般规则”的参考资料吗?我绝对不会仅仅因为文档没有明确说明调用是线程安全的,就认为调用是线程安全的。但请注意,我的回答也表明Sun明确声明他们自己的Javadoc不是线程安全的