Steve
Steve

Reputation: 2816

Java: Rule Of Thumb For Using Synchrozined Collections?

I was reading this Stackoverflow thread about using StringBuilder versus StringBuffer.

The bottom line seemed to be that the two collections were the same thing except that a StringBuffer is synchronized, is a thread safe and does a little less well in performance as compared to StringBuilder which are not those things.

Someone brought up how a similar relationship existed between ArrayList and Vector.

Is it a good (safe) rule of thumb to NOT use synchronized collections ( or anything else ) unless I am consciously creating multiple threads?

In other words, I got the message "Use the new StringBuilder wherever possible.", what I want to know is, how can I be sure it is possible?

Am I safe using non-synchronized collections as long as I don't create new threads intentionally?

Upvotes: 2

Views: 269

Answers (7)

Stephen C
Stephen C

Reputation: 718826

Is it a good (safe) rule of thumb to NOT use synchronized collections ( or anything else ) unless I am consciously creating multiple threads?

No it is not.

There are situations where multiple threads are involved, even though you don't consciously create them. For example, any application that uses Swing or Servlets has the potential for interactions between application code on different threads. (And you could even argue that you don't explicitly create threads if you use a standard thread-pool implementation.)

And further more, using a synchronized collection does not necessarily buy you thread safety.

But you are correct in the sense that using a synchronized data structure when there is no possibility of multiple threads using the data structure is (somewhat) wasteful. But nowhere like as wasteful as in the old days when mutexes were expensive.


In other words, I got the message "Use the new StringBuilder wherever possible.", what I want to know is, how can I be sure it is possible?

By understanding your code. Can the StringBuilder be seen by other threads? If not, then it safe to use it. Otherwise, the threads that share the StringBuilder need to synchronize. One way to do that might be to use a StringBuffer, but that won't necessarily give you the right synchronization granularity.

Here's a simple example:

  public String nTimes(String str, int n) {
      StringBuilder sb = new StringBuilder();
      for (int i = 1; i <= n; i++) sb.append(str);
      return sb.toString();
  }

In the above, the StringBuilder in sb can never be seen by another thread, so there is no need to synchronize it.

Upvotes: 0

paulsm4
paulsm4

Reputation: 121669

This link says it best:

* http://javahowto.blogspot.com/2006/08/stringbuilder-vs-stringbuffer.html

StringBuilder was introduced in JDK 1.5. What's the difference between StringBuilder and StringBuffer? According to javadoc, StringBuilder is designed as a replacement for StringBuffer in single-threaded usage. Their key differences in simple term:

  • StringBuffer is designed to be thread-safe and all public methods in StringBuffer are synchronized. StringBuilder does not handle thread-safety issue and none of its methods is synchronized.

  • StringBuilder has better performance than StringBuffer under most circumstances.

  • Use the new StringBuilder wherever possible.

From my own experience:

  • For any serious string manipulation, always use StringBuilder (never "String")

  • I've never had any occasion to use StringBuffer (I always just use "StringBuilder" instead).

  • Only if the same string-in-progress is being accessed concurrently from multiple threads should you even consider "StringBuffer". And even then, you might well find it easier/more efficient to use your own locking instead.

IMHO...

Upvotes: 0

Louis Wasserman
Louis Wasserman

Reputation: 198103

Use unsynchronized things until you're sure that you need synchronization.

Part of the issue with e.g. StringBuffer and Vector is that they're not always synchronized in the right way. For Vector, it's not always what you need to have every operation be synchronized individually; frequently what you actually want is to synchronize blocks of operations...for which Vector isn't necessarily any better than ArrayList or a Collections.synchronizedList.

When you know you're using concurrency and multiple threads, then work out the details of what synchronization you need, but just swapping StringBuffer in for StringBuilder will only give you a false sense of security -- even if you decide to use concurrency later, that's not necessarily the right kind of concurrency.

(If you're not currently using threading, then it's absolutely fine -- even recommended -- to find-and-replace StringBuffer to StringBuilder. The above arguments are for the reverse direction.)

Upvotes: 5

Eugene Kuleshov
Eugene Kuleshov

Reputation: 31795

It seem like you're asking multiple questions here. So, first of all, it is indeed a good idea to avoid synchronization unless absolutely necessary.

On your second question it is also safe to replace StringBuilder with StringBuffer and vice versa, unless their values can be changed from multiple threads.

Upvotes: 1

John Vint
John Vint

Reputation: 40256

I would say always use non-blocking anything until you know how to answer this question yourself. It's really easy to synchronize everything its also really easy to create and start threads. It takes a while to understand when to use a synchronized and when to create a thread.

You should start by reading Java Concurrency in Practice.

Upvotes: 1

assylias
assylias

Reputation: 328618

Doing it on a whole code base automatically sounds a bit dangerous without further analysis, unless you are 100% positive that those objects (Vectors, StringBuffers) are not shared accross threads, or if the choice of a synchronized object was not driven by a thread safety analysis in the first place.

One simple case where you can do the swap without risk is local variables, which obviously can't be shared accross threads (unless you return them).

Upvotes: 0

Bharat Sinha
Bharat Sinha

Reputation: 14363

We are using StringBuilder instead of StringBuffer as we don't think so that multiple threads will cause us issues.

Upvotes: 0

Related Questions