开发者

java call function from multiple threads not declared as thread safe

开发者 https://www.devze.com 2023-01-10 12:22 出处:网络
There is a JDK function that, although the javadocs does not declare it as thread-safe, from looking a开发者_开发百科t the code in Google, it seems that I could get the result I want by calling it fro

There is a JDK function that, although the javadocs does not declare it as thread-safe, from looking a开发者_开发百科t the code in Google, it seems that I could get the result I want by calling it from multiple threads without undesirable side-effects, since the function uses mainly stack variables. So it does not matter if it has synchronized blocks. I am wondering though if I am missing something and eventually run into trouble. The function is connection.call(requestMsg, url); of SOAPConnection from SAAJ api. Any pointer on how I should analyze this in order to decide to use it from multiple threads or not?

Thanks!


Hell No. If it's not specifically documented as thread safe, we shall not assume that. Don't mind Sun's recommendation written in the days of Vector, Hashtable, StringBuffer, old java memory model and single processor machines. The fashion has turned. We are living in a dramatically different world of java concurrency.

For a mutable class, it's far more likely that it's written with one thread in mind. So I would argue that without doc we'll have to assume it's for single thread. External synchronization must be used in a bigger picture of things. (That usually helps performance compared to locking at finer level).

For a class that's actually designed to be used in multiple threads, it must provide painstakingly detailed document of how it behaves. It is nonsense to mark it as simply "thread safe". There are too many things to explain and document, check out any concurrency class.

Therefore, it is nonsense to assume a "default" thread safety mode. It doesn't mean anything.

--

For you specific query, if the implementation is like this

constructor()
  open socket

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

close()
  close socket

Without synchronization on call(), this is obviously UNSAFE. If you have concurrent reads/writes on a TCP connection, chaos assured.

Suppose I wrote a safer implementation, would I keep silent? Of course not. I'll tell the user that concurrent call()s are allowed; each request is written atomically; pipeline is used for throughput; responses are returned in the order of requests; close() can be invoked anytime by any thread; outstanding calls will have x seconds to finish gracefully; after that the connection is aborted; any thread waiting on call() will receive an excpetion.


The following quote comes from "How to Write Doc Comments for the Javadoc Tool"

The Java Platform API Specification is a contract between callers and implementations.

The Specification describes all aspects of the behavior of each method on which a caller can rely. It does not describe implementation details, such as whether the method is native or synchronized. The specification should describe (textually) the thread-safety guarantees provided by a given object. In the absence of explicit indication to the contrary, all objects are assumed to be "thread-safe" (i.e., it is permissible for multiple threads to access them concurrently). It is recognized that current specifications don't always live up to this ideal.

To me this says, that you ideally should be able to assume that the standard Java APIs are thread-safe unless it is stated otherwise. But the last sentence says to me that this is a rather dangerous thing to assume that this is always true. Certainly, for most of Swing APIs you should NOT assume thread-safety.

I think that the following is a reasonable approach to deciding what you can rely on to be thread-safe:

  • If the javadoc explicitly says something is thread-safe, you can rely on it being thread-safe going forward.
  • If the javadoc explicitly says something is not thread-safe, you can rely on it being non-thread-safe going forward.
  • If the javadoc says nothing, AND a careful examination of the source code tells you that it is thread-safe, you can rely on it being thread-safe going forward.
  • If the javadoc says nothing, AND a careful examination of the source code tells you that it is not thread-safe, all bets are off. It could be a javadoc error, or a shortcoming of the current implementation.

(This is based on the observation that Sun / Oracle are unlikely to make changes that break backwards compatibility. Changing thread-safety characteristics of standard APIs could cause of insidious concurrency bugs ... and is therefore doubly unlikely.)


I am with Stephen - If it does not explicitly say that it is Thread Safe, assume it is not.
That being said, I looked through the code and it looks OK after about a 15 minute inspection.

The main thing is to see if there are any shared variables between threads and if they would be affected by being called by two or more threads concurrently. Of course this can be a lengthy and tricky process, since a class may be composed of several other classes, which in turn are composed of several others.

If it were me, I would restructure my code to make sure that I did not call in a multithreaded way, since debugging this would be a nightmare and I have no guarantees that it will work 100% of the time.

It is your call: As Dirty Harry once said: "Do you feel lucky today ?, well do you ?"

On another note, I answered this question and the answer may also apply to this.


The general rule is that methods And classes are thread-safe unless stated to the contrary. So for example RMI methods are thread-safe, ditto this one.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号