Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.help > #2402 > unrolled thread
| Started by | Steve <tinker123@gmail.com> |
|---|---|
| First post | 2013-01-01 15:46 -0500 |
| Last post | 2013-01-11 08:25 -0500 |
| Articles | 11 on this page of 31 — 8 participants |
Back to article view | Back to comp.lang.java.help
Safety Of Non-Synchronized Collections Steve <tinker123@gmail.com> - 2013-01-01 15:46 -0500
Re: Safety Of Non-Synchronized Collections Knute Johnson <nospam@knutejohnson.com> - 2013-01-01 14:18 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-01 15:43 -0800
Re: Safety Of Non-Synchronized Collections markspace <markspace@nospam.nospam> - 2013-01-01 16:17 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-02 11:12 -0800
Re: Safety Of Non-Synchronized Collections markspace <markspace@nospam.nospam> - 2013-01-02 12:56 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-02 17:46 -0800
Re: Safety Of Non-Synchronized Collections Roedy Green <see_website@mindprod.com.invalid> - 2013-01-03 05:59 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-03 15:30 -0800
Re: Safety Of Non-Synchronized Collections Roedy Green <see_website@mindprod.com.invalid> - 2013-01-09 12:17 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-09 12:56 -0800
Re: Safety Of Non-Synchronized Collections Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-01-09 13:10 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-09 14:51 -0800
Re: Safety Of Non-Synchronized Collections Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-01-09 15:22 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-09 16:26 -0800
Re: Safety Of Non-Synchronized Collections Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-01-09 16:42 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-09 16:54 -0800
Re: Safety Of Non-Synchronized Collections Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-01-10 10:30 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-10 10:58 -0800
Re: Safety Of Non-Synchronized Collections markspace <markspace@nospam.nospam> - 2013-01-09 16:50 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-09 16:59 -0800
Re: Safety Of Non-Synchronized Collections markspace <markspace@nospam.nospam> - 2013-01-10 08:18 -0800
Re: Safety Of Non-Synchronized Collections Lew <lewbloch@gmail.com> - 2013-01-10 10:49 -0800
Re: Safety Of Non-Synchronized Collections Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> - 2013-01-10 13:37 +0200
Re: Safety Of Non-Synchronized Collections Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-10 09:27 -0500
Re: Safety Of Non-Synchronized Collections Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> - 2013-01-10 17:14 +0200
Re: Safety Of Non-Synchronized Collections Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-10 11:44 -0500
Re: Safety Of Non-Synchronized Collections Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> - 2013-01-10 23:41 +0200
Re: Safety Of Non-Synchronized Collections Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-10 17:14 -0500
Re: Safety Of Non-Synchronized Collections Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> - 2013-01-11 09:10 +0200
Re: Safety Of Non-Synchronized Collections Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-11 08:25 -0500
Page 2 of 2 — ← Prev page 1 [2]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2013-01-09 16:59 -0800 |
| Message-ID | <faf0aa77-0299-48ea-9640-69124203b766@googlegroups.com> |
| In reply to | #2424 |
markspace wrote: > Lew wrote: >> http://rayfd.me/2007/11/11/when-a-synchronized-class-isnt-threadsafe/ > >> This is elementary concurrency gotcha lore. > > Note this sentence from the article: "Changing the synchronized List to > Vector doesn't help either." Exactly! MY POINT! > Vector is thread safe. Objects wrapped by Collections.synchronized() 'Vector' is *not* thread safe! That's the point of that article. > are thread safe. This does not guarantee that every use of those > classes is safe, or correct. > > Their example is of a single collection which is accessed by multiple > threads. As they show their example produces errors. This is an issue > of atomicity, not thread safety. The single collection is still It is an issue with the idea that people confuse synchronized methods with thread safety. From the Brian Goetz article I quoted upthread: "Thread-safe Thread-safe objects have the properties described above in the section "Thread Safety" -- that constraints imposed by the class's specification continue to hold when the object is accessed by multiple threads, regardless of how the threads are scheduled by the runtime environment, without any additional synchronization. This thread-safety guarantee is a strong one -- many classes, like Hashtable or Vector, will fail to meet this stringent definition." > perfectly safe, in spite of the errors. There are no data races. There are synchronization issues because a person coding that way thinks the synchronized-method class is thread safe when it isn't. You, too, are pulling No True Scotsman, and I will still use Brian Goetz's definitions over yours. > However, the program produces errors because it is poorly designed. It > requires atomicity, and synchronized methods don't provide that across > multiple method calls. Because the class *is not thread safe*! > So the problem is really one of quibbling over terminology. Thread Terminology matters. It's worth "quibbling". (Calling it by something pejorative does not diminish its real importance.) > safety and atomicity both fall under the more general heading of > concurrency and concurrent programming. Thread safety and atomicity are A.k.a., threads. > not the same thing. They overlap a bit, but not much, so it's best to Again, look at the definition and stop changing it. > actually understand what is being discussed. In Java, thread safe means > an absence of data races, but that's all. It says nothing about > atomicity, or the correctness of any given program. Your definition is wrong. -- Lew
[toc] | [prev] | [next] | [standalone]
| From | markspace <markspace@nospam.nospam> |
|---|---|
| Date | 2013-01-10 08:18 -0800 |
| Message-ID | <kcmpl4$6jd$2@dont-email.me> |
| In reply to | #2426 |
On 1/9/2013 4:59 PM, Lew wrote: > From the Brian Goetz article I quoted upthread: I didn't see that article upthread. Do you mean this one? <http://www.ibm.com/developerworks/java/library/j-jtp09263/index.html>
[toc] | [prev] | [next] | [standalone]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2013-01-10 10:49 -0800 |
| Message-ID | <bc43b7ef-3ef7-4963-805c-29c77d830510@googlegroups.com> |
| In reply to | #2430 |
markspace wrote: > Lew wrote: >> From the Brian Goetz article I quoted upthread: > > I didn't see that article upthread. Do you mean this one? > > <http://www.ibm.com/developerworks/java/library/j-jtp09263/index.html> Aye. -- Lew
[toc] | [prev] | [next] | [standalone]
| From | Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> |
|---|---|
| Date | 2013-01-10 13:37 +0200 |
| Message-ID | <lvd2xdw9p0.fsf@saunalahti.fi> |
| In reply to | #2420 |
Daniel Pitts <newsgroup.nospam@virtualinfinity.net> writes: > On 1/9/13 2:51 PM, Lew wrote: >> 'StringBuffer' is no more thread safe than any other class with >> synchronized methods. > Which is more safe than other classes without synchronized methods. > They are thread-safe to the point that each method call is atomic. What > else could you ask for? They didn't lie. Whenever thread safety is needed, you mostly need to synchronize not only the single method call to an instance of StringBuffer or some other class of the jdk, but also some context around it. And when you add a synchronized block around some code containing the StringBuffer call, the synchronization of the StringBuffer method is most likely not needed any more, because of your own synchronized block. And then you can just use StringBuilder. Of course, there may be situations where the StringBuffer method is all that needs to be syncrhonized, and that's where StringBuffer should be used. -- Jukka Lahtinen
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2013-01-10 09:27 -0500 |
| Message-ID | <kcmj4t$vkm$1@dont-email.me> |
| In reply to | #2427 |
On 1/10/2013 6:37 AM, Jukka Lahtinen wrote:
> Daniel Pitts <newsgroup.nospam@virtualinfinity.net> writes:
>> On 1/9/13 2:51 PM, Lew wrote:
>
>>> 'StringBuffer' is no more thread safe than any other class with
>>> synchronized methods.
>
>> Which is more safe than other classes without synchronized methods.
>> They are thread-safe to the point that each method call is atomic. What
>> else could you ask for? They didn't lie.
>
> Whenever thread safety is needed, you mostly need to synchronize not
> only the single method call to an instance of StringBuffer or some other
> class of the jdk, but also some context around it.
> And when you add a synchronized block around some code containing the
> StringBuffer call, the synchronization of the StringBuffer method is
> most likely not needed any more, because of your own synchronized
> block. And then you can just use StringBuilder.
This is probably not the case, because another thread might
call an (unsynchronized) StringBuilder method while you're in
the middle of your synchronized block:
StringBuilder sb = ...;
// Thread T1:
synchronized(sb) {
if (sb.charAt(sb.length() - 1) == '\n') {
sb.deleteCharAt(sb.length() - 1);
}
}
// Thread T2:
sb.append("Gotcha!");
The synchronization in T1's code is no protection against
interference from T2. If `sb' were changed from a StringBuilder
to a StringBuffer, the race condition would disappear.
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> |
|---|---|
| Date | 2013-01-10 17:14 +0200 |
| Message-ID | <lvbocxdq9t.fsf@saunalahti.fi> |
| In reply to | #2428 |
Eric Sosman <esosman@comcast-dot-net.invalid> writes:
> On 1/10/2013 6:37 AM, Jukka Lahtinen wrote:
>> Daniel Pitts <newsgroup.nospam@virtualinfinity.net> writes:
>>> On 1/9/13 2:51 PM, Lew wrote:
>>>> 'StringBuffer' is no more thread safe than any other class with
>>>> synchronized methods.
>>> Which is more safe than other classes without synchronized methods.
>>> They are thread-safe to the point that each method call is atomic. What
>>> else could you ask for? They didn't lie.
>> Whenever thread safety is needed, you mostly need to synchronize not
>> only the single method call to an instance of StringBuffer or some other
>> class of the jdk, but also some context around it.
> This is probably not the case, because another thread might
> call an (unsynchronized) StringBuilder method while you're in
> the middle of your synchronized block:
If you use the same instance in many places, potentially in different
threads, you should of course synchronize all of them using the same
lock.
> StringBuilder sb = ...;
> // Thread T1:
> synchronized(sb) {
> if (sb.charAt(sb.length() - 1) == '\n') {
> sb.deleteCharAt(sb.length() - 1);
> }
> }
This is an example of what I wrote above. You need that synchronization
to prevent others from modifying sb between the charAt, length and
deletCharAt calls anyway.
Using StringBuffer instead of StringBuilder does NOT accomplish that.
> // Thread T2:
> sb.append("Gotcha!");
And so, this should be
synchronized(sb) {
sb.append("Gotcha?");
}
> The synchronization in T1's code is no protection against
> interference from T2. If `sb' were changed from a StringBuilder
> to a StringBuffer, the race condition would disappear.
Neither is using StringBuffer.
Like I said, you could be in trouble if T2 makes that call somewhere
between the calls to the first sb.length() and sb.deletCharAt in T1 even
if sb is a StringBuffer.
--
Jukka Lahtinen
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2013-01-10 11:44 -0500 |
| Message-ID | <kcmr59$hp6$1@dont-email.me> |
| In reply to | #2429 |
On 1/10/2013 10:14 AM, Jukka Lahtinen wrote:
> Eric Sosman <esosman@comcast-dot-net.invalid> writes:
>> On 1/10/2013 6:37 AM, Jukka Lahtinen wrote:
>>> Daniel Pitts <newsgroup.nospam@virtualinfinity.net> writes:
>>>> On 1/9/13 2:51 PM, Lew wrote:
>
>>>>> 'StringBuffer' is no more thread safe than any other class with
>>>>> synchronized methods.
>
>>>> Which is more safe than other classes without synchronized methods.
>>>> They are thread-safe to the point that each method call is atomic. What
>>>> else could you ask for? They didn't lie.
>
>>> Whenever thread safety is needed, you mostly need to synchronize not
>>> only the single method call to an instance of StringBuffer or some other
>>> class of the jdk, but also some context around it.
>
>> This is probably not the case, because another thread might
>> call an (unsynchronized) StringBuilder method while you're in
>> the middle of your synchronized block:
>
> If you use the same instance in many places, potentially in different
> threads, you should of course synchronize all of them using the same
> lock.
>
>> StringBuilder sb = ...;
>> // Thread T1:
>> synchronized(sb) {
>> if (sb.charAt(sb.length() - 1) == '\n') {
>> sb.deleteCharAt(sb.length() - 1);
>> }
>> }
>
> This is an example of what I wrote above. You need that synchronization
> to prevent others from modifying sb between the charAt, length and
> deletCharAt calls anyway.
> Using StringBuffer instead of StringBuilder does NOT accomplish that.
>
>> // Thread T2:
>> sb.append("Gotcha!");
>
> And so, this should be
>
> synchronized(sb) {
> sb.append("Gotcha?");
> }
>
>> The synchronization in T1's code is no protection against
>> interference from T2. If `sb' were changed from a StringBuilder
>> to a StringBuffer, the race condition would disappear.
>
> Neither is using StringBuffer.
> Like I said, you could be in trouble if T2 makes that call somewhere
> between the calls to the first sb.length() and sb.deletCharAt in T1 even
> if sb is a StringBuffer.
If T2 makes such a call while T1 is in the synchronized block,
T2 will stall until T1's synchronized block finishes (or perhaps
longer). No race, no trouble.
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> |
|---|---|
| Date | 2013-01-10 23:41 +0200 |
| Message-ID | <lvr4lspvge.fsf@saunalahti.fi> |
| In reply to | #2431 |
Eric Sosman <esosman@comcast-dot-net.invalid> writes:
> On 1/10/2013 10:14 AM, Jukka Lahtinen wrote:
>> Eric Sosman <esosman@comcast-dot-net.invalid> writes:
>>> On 1/10/2013 6:37 AM, Jukka Lahtinen wrote:
>>>> Whenever thread safety is needed, you mostly need to synchronize not
>>>> only the single method call to an instance of StringBuffer or some other
>>>> class of the jdk, but also some context around it.
>>> This is probably not the case, because another thread might
>>> call an (unsynchronized) StringBuilder method while you're in
>>> the middle of your synchronized block:
>> If you use the same instance in many places, potentially in different
>> threads, you should of course synchronize all of them using the same
>> lock.
>>> StringBuilder sb = ...;
>>> // Thread T1:
>>> synchronized(sb) {
>>> if (sb.charAt(sb.length() - 1) == '\n') {
>>> sb.deleteCharAt(sb.length() - 1);
>>> }
>>> }
>>> // Thread T2:
>>> sb.append("Gotcha!");
>> And so, this should be
>> synchronized(sb) {
>> sb.append("Gotcha?");
>> }
>>> The synchronization in T1's code is no protection against
>>> interference from T2. If `sb' were changed from a StringBuilder
>>> to a StringBuffer, the race condition would disappear.
>> Like I said, you could be in trouble if T2 makes that call somewhere
>> between the calls to the first sb.length() and sb.deletCharAt in T1 even
>> if sb is a StringBuffer.
> If T2 makes such a call while T1 is in the synchronized block,
> T2 will stall until T1's synchronized block finishes (or perhaps
> longer). No race, no trouble.
Only if you add the synchronization also to T2, like I did
above. Without that, nothing will prevent T2 from calling sb.append
between the separate calls from T1 to sb, no matter whether sb is
StringBuffer or StringBuilder.
--
Jukka Lahtinen
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2013-01-10 17:14 -0500 |
| Message-ID | <kcneh0$kmh$1@dont-email.me> |
| In reply to | #2435 |
On 1/10/2013 4:41 PM, Jukka Lahtinen wrote:
> Eric Sosman <esosman@comcast-dot-net.invalid> writes:
>> On 1/10/2013 10:14 AM, Jukka Lahtinen wrote:
>>> Eric Sosman <esosman@comcast-dot-net.invalid> writes:
>>>> On 1/10/2013 6:37 AM, Jukka Lahtinen wrote:
>
>>>>> Whenever thread safety is needed, you mostly need to synchronize not
>>>>> only the single method call to an instance of StringBuffer or some other
>>>>> class of the jdk, but also some context around it.
>
>>>> This is probably not the case, because another thread might
>>>> call an (unsynchronized) StringBuilder method while you're in
>>>> the middle of your synchronized block:
>
>>> If you use the same instance in many places, potentially in different
>>> threads, you should of course synchronize all of them using the same
>>> lock.
>
>>>> StringBuilder sb = ...;
>>>> // Thread T1:
>>>> synchronized(sb) {
>>>> if (sb.charAt(sb.length() - 1) == '\n') {
>>>> sb.deleteCharAt(sb.length() - 1);
>>>> }
>>>> }
>
>>>> // Thread T2:
>>>> sb.append("Gotcha!");
>
>>> And so, this should be
>>> synchronized(sb) {
>>> sb.append("Gotcha?");
>>> }
>
>>>> The synchronization in T1's code is no protection against
>>>> interference from T2. If `sb' were changed from a StringBuilder
>>>> to a StringBuffer, the race condition would disappear.
>
>>> Like I said, you could be in trouble if T2 makes that call somewhere
>>> between the calls to the first sb.length() and sb.deletCharAt in T1 even
>>> if sb is a StringBuffer.
>
>> If T2 makes such a call while T1 is in the synchronized block,
>> T2 will stall until T1's synchronized block finishes (or perhaps
>> longer). No race, no trouble.
>
> Only if you add the synchronization also to T2, like I did
> above. Without that, nothing will prevent T2 from calling sb.append
> between the separate calls from T1 to sb, no matter whether sb is
> StringBuffer or StringBuilder.
Quoth the Javadoc for StringBuffer:
"Whenever an operation occurs involving a source sequence
(such as appending or inserting from a source sequence)
this class synchronizes only on the string buffer performing
the operation [...]"
Therefore, StringBuffer's append() method synchronizes on the
StringBuffer instance being appended to, using the instance's
own monitor. That's the same monitor used by the explicit
`synchronized' in my code example (modified to use StringBuffer
instead of StringBuilder), so there is a mutual exclusion between
the body of append() and the body of the `synchronized' block.
The two executions cannot overlap, interfere, intertwine, entangle,
or cohabit.
(Oddly enough, although StringBuffer's Javadoc says "the
methods are synchronized," only for source-destination methods
does it actually specify what object's lock is used -- and even
that comes as a by-product of saying what object's lock *isn't*
used. Had my example used setCharAt(), say, there could have
been a quibble about whether a mutual exclusion actually exists --
but with append() there's no question.)
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | Jukka Lahtinen <jtfjdehf@hotmail.com.invalid> |
|---|---|
| Date | 2013-01-11 09:10 +0200 |
| Message-ID | <lvzk0gnqjy.fsf@saunalahti.fi> |
| In reply to | #2436 |
Eric Sosman <esosman@comcast-dot-net.invalid> writes: > On 1/10/2013 4:41 PM, Jukka Lahtinen wrote: >> Eric Sosman <esosman@comcast-dot-net.invalid> writes: >>> If T2 makes such a call while T1 is in the synchronized block, >>> T2 will stall until T1's synchronized block finishes (or perhaps >>> longer). No race, no trouble. >> Only if you add the synchronization also to T2, like I did > Quoth the Javadoc for StringBuffer: > "Whenever an operation occurs involving a source sequence > (such as appending or inserting from a source sequence) > this class synchronizes only on the string buffer performing > the operation [...]" Oh, I stand corrected. It works in this case. But still I claim that when synchronization is needed, it is MOSTLY needed for a block broader than just the single call to a method of a jdk class instance. (And before anybody calls for "true Scotsman", I remembered to include the word mostly in my original claim as well.) -- Jukka Lahtinen
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2013-01-11 08:25 -0500 |
| Message-ID | <kcp3t8$pg4$1@dont-email.me> |
| In reply to | #2437 |
On 1/11/2013 2:10 AM, Jukka Lahtinen wrote:
> [...]
> But still I claim that when synchronization is needed, it is MOSTLY
> needed for a block broader than just the single call to a method of a
> jdk class instance.
Yes, often. Somebody elsethread made a distinction between
"operations" and "method calls" (I'm paraphrasing, because I can't
find the post at the moment). If all the necessary methods are
synchronized, they are individually thread-safe -- but if an
"operation" uses multiple method calls, the "operation" might
not be.
This principle even applies to atomics, which synchronize
without `synchronized'. With an AtomicInteger named `atom',
this is thread-safe:
atom.addAndGet(3);
... but this is not:
// Make sure the value is even:
atom.addAndGet(atom.get() & 1);
Each of `get' and `addAndGet' is individually thread-safe, but
the "operation" composed of both is not.
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.java.help
csiph-web