Best way to synchronize in a Singleton

I have this classimport java.util.ArrayList;

import java.util.List;

publicclass SynchIssues

{

private List values =new ArrayList();

privatestaticfinal SynchIssues singleton =new SynchIssues();

publicstatic SynchIssues getInstance()

{

return singleton;

}

publicvoid addValue(String value)

{

synchronized(singleton)

{

values.add(value);

}

}

public String getValue(int i)

{

synchronized (singleton)

{

return (String) values.get(i);

}

}

}

And i synchronize on the singleton itself , but some collegue uses a different approach

import java.util.ArrayList;

import java.util.List;

publicclass SynchIssues2

{

private List values =new ArrayList();

privatestaticfinal SynchIssues2 singleton =new SynchIssues2();

publicstatic SynchIssues2 getInstance()

{

return singleton;

}

publicsynchronizedvoid addValue(String value)

{

values.add(value);

}

publicsynchronized String getValue(int i)

{

return (String) values.get(i);

}

}

He uses synchronize on the methods in stead of the SIngleton.

What approach is best ?

Are both approaches thread safe ?

Do teh different approaches risk deadlocking when different thread will be accessing the classes ?

[3304 byte] By [pgeuensa] at [2007-10-2 9:57:50]
# 1
AFAIK, that's exactly the sameI'll give a check to see if there's a difference in bytecodes produced ;-)
Torajiroua at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

kk thanks in advance ! not the bytecode expert myself

I ran into a third way of implementing this

import java.util.ArrayList;

import java.util.List;

import java.util.Collections;

public class SynchIssues3

{

private List values = Collections.synchronizedList(new ArrayList());

private static final SynchIssues3 singleton = new SynchIssues3();

public static SynchIssues3 getInstance()

{

return singleton;

}

public void addValue(String value)

{

values.add(value);

}

public String getValue(int i)

{

return (String) values.get(i);

}

}

Would this be similar too ?

pgeuensa at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 3
yeah bytecode is different, but that's quite normal ;-)bytecode is even different when you replace synchronized(singleton) by synchronized(this), actuallynote that your co-worker's solution produces a shorter .class file... (not that it really matters but...)
Torajiroua at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

> kk thanks in advance ! not the bytecode expert

> myself

I'm not either, just comparing files in an hexadecimal editor ;-)

>

> I ran into a third way of implementing this

>

> > import java.util.ArrayList;

> import java.util.List;

> import java.util.Collections;

>

> public class SynchIssues3

> {

> private List values =

> = Collections.synchronizedList(new ArrayList());

>

> private static final SynchIssues3 singleton = new

> ew SynchIssues3();

>

>public static SynchIssues3 getInstance()

>{

>return singleton;

>}

>

>public void addValue(String value)

>{

>values.add(value);

>}

>

>public String getValue(int i)

>{

>return (String) values.get(i);

>}

> }

>

>

>

> Would this be similar too ?

not quite sure about this one... I'm not a race-condition expert either... :(

Torajiroua at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 5
size doesnt matter indeed Just need the most thread safe
pgeuensa at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 6
> size doesnt matter indeed > ;-)
Torajiroua at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 7
in a word: don't.google on double checked locking. it's broken.%
duffymoa at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

What do you need to do exactly? What does "the most thread-safe" mean?

If I read correctly your code samples, the fact that the "shared object" is a singleton is not relevant. Your point seems to be more about a generic issue of "synchronizing access to a shared collection".

Without resorting to bytecode examination, it seems your 3 code samples look equivalent as far as individual add() and get() operations are concerned: each operation is atomic, and only one thread is actually reading/modifying the collection at a given time. In this regard each of these operations can be told "thread-safe".

However it gives absolutely no guarantee about several operations executed in sequence : two threads executing such a sequence would probably see their get() and add() interleaved. This may or may not cause a problem depending on your application (what you do about the data in the collection, and in particular how you react to reaching the end of the list).

If you want this kind of guarantee of per-sequence atomicity (a sequence of, e.g., get() is executed without any other thread modifying the collection in between), you have to make sure each client synchronizes on the collection (or on the singleton, if it's the only wrapper) around the whole block of the sequence:

SynchIssueX singleton = SynchIssueX.getInstance();

// make sure no other thread may read any value before I've added them all:

synchronized (singleton) {

singleton.add(value1);

singleton.add(value2);

singleton.add(value3);

}

jdupreza at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 9
> in a word: don't.> > google on double checked locking. it's broken.> > %Where's the double-cheked locking in this thread? Did I miss it?
dubwaia at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 10
nope, i went back and re-read the code. knee jerk reaction. sorry.%
duffymoa at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

>What do you need to do exactly? What does "the most thread-safe" mean?

I just wonder if there is a difference or lurking flaw in the different ways of synchronizing the atomic operations

> the fact that the "shared object" is a singleton is not relevant.

Correct

>It seems your 3 code samples look equivalent

I was thinking the same just wondered if i missed some detail

>f you want this kind of guarantee of per-sequence atomicity

Good point , the collection will be filled with several items all at once so i need to be carefull with that too.

pgeuensa at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 12
The first approach is not good.The 2nd approach is the best.See http://www-128.ibm.com/developerworks/java/library/j-dcl.html for an excelent and complete explanation.
vikrulesa at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

> The first approach is not good.

> The 2nd approach is the best.

>

> See

> http://www-128.ibm.com/developerworks/java/library/j-d

> cl.html for an excelent and complete explanation.

1. This is an old thread.

2. The above suggestion that the first is "not good" is wrong.

3. The link has nothing to do with the several options that are being discussed.

jschella at 2007-7-17 0:03:15 > top of Java-index,Other Topics,Patterns & OO Design...