有一个JDK函数虽然javadocs没有声明它是线程安全的,但是从查看Google中的代码看来,似乎我可以通过从多个线程调用它来获得我想要的结果而没有不希望的方面 - 效果,因为该函数主要使用堆栈变量。所以它是否具有同步块并不重要。我想知道如果我错过了什么并最终遇到麻烦。 该函数是connection.call(requestMsg,url);来自SAAJ api的SOAPConnection。关于如何分析这个以决定是否从多个线程使用它的任何指针?
谢谢!
答案 0 :(得分:4)
地狱否。如果它没有具体记录为线程安全,我们不会假设。不要介意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
如果没有call()同步,这显然是UNSAFE。如果你在TCP连接上有并发读/写,那就确保混乱。
假设我写了一个更安全的实现,我会保持沉默吗?当然不是。我告诉用户允许并发call();每个请求都是原子地写的;管道用于吞吐量;响应按请求顺序返回;任何线程都可以随时调用close();优秀的电话将有x秒优雅地完成;之后连接中止;等待call()的任何线程都会收到一个excpetion。
答案 1 :(得分:1)
以下引用来自"How to Write Doc Comments for the Javadoc Tool"
Java平台API规范是调用者和实现之间的契约。
规范描述了调用者可以依赖的每种方法的行为的所有方面。它没有描述实现细节,例如方法是本机还是同步。规范应该(文本地)描述给定对象提供的线程安全保证。在没有相反的明确指示的情况下,假设所有对象都是“线程安全的”(即,允许多个线程同时访问它们)。人们认识到,目前的规格并不总是符合这一理想。
对我来说,除非另有说明,否则理想情况下应该能够认为标准Java API是线程安全的。但是最后一句话告诉我,这是一个相当危险的事情,假设这一直是真的。当然,对于大多数Swing API,您不应该假设线程安全。
我认为以下是决定您可以依赖线程安全的合理方法:
(这是基于观察到Sun / Oracle不太可能进行破坏向后兼容性的更改。更改标准API的线程安全特性可能会导致阴险的并发错误......因此不太可能。)
答案 2 :(得分:1)
我和斯蒂芬在一起 - 如果它没有明确说它是线程安全,那么假设它不是。
话虽这么说,我查看了代码,看了大约15分钟后看起来还不错。
主要的是查看线程之间是否存在任何共享变量,以及它们是否会受到两个或多个线程同时调用的影响。当然,这可能是一个漫长而棘手的过程,因为一个类可能由几个其他类组成,而这些类又由其他几个类组成。
如果是我,我会重构我的代码,以确保我没有以多线程方式调用,因为调试这将是一场噩梦,我无法保证它将在100%的时间内工作。
这是你的电话:正如Dirty Harry曾经说过的那样:“你今天感觉幸运吗?你呢?”
另一方面,我回答this question,答案也适用于此。
答案 3 :(得分:-3)
一般规则是方法和类是线程安全的,除非另有说明。因此,例如RMI方法是线程安全的,同样也适用于此。