Fixing Double-Checked Locking using Volatile
Oooh - what a scandalous subject title! :)
Anyhow, I was expanding my knowledge on why the double-checked locking idiom used in Singleton classes fails (after reading that JSR-133 is not going to fix the problem!), when I read http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html and found a spicy section titled "Fixing Double-Checked Locking using Volatile" (at the very bottom of the document).
As it is quite hard to find information (all sources revisit all the basic problems), I was wondering if anybody could back this up/refute it.
Just one more thing. I anticipate that many people who are researching this matter would like to have this clarified, so it would be beneficial to keep posts very much on topic. There is already a lot of information available about double locking failures in general.
The problem this post faces lies in a lot of statements saying "using volatile will NOT fix double-checked locking" that refer (I think) to the current JDK.
Thanks heaps!
Volatile only checks that not more than one thread is accessing the variable at the same time (amongst other things of course), so in the example, it could cause problems. Let me explain a little here. Given a situation where two threads wish to aquire the Helper:
Step 1: Thread 1 enters the method and checks the helper status
and sees that it is null.
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) { // <!-- Thread 1 requires helper, and sees that it is null
synchronized(this) {
if (helper == null)
helper = new Helper();
return helper;
}Step 2: Thread 2 enters the method, before the lock can be
acquired on the this-object and notices that the helper is
null.
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) { // <!-- Thread 2 requires helper also
synchronized(this) { // and it is still null
if (helper == null)
helper = new Helper();
return helper;
}Step 3: The first Thread creates a new Helper
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) { // <!-- Thread 2 waiting for lock realeas
synchronized(this) {
if (helper == null)
helper = new Helper(); // <!-- Thread 1 creating new Helper
return helper; //
}Now for Step 4, there are a few possibilites here. Either Thread 1 returns the helper it created, or Thread 2 can create the new Helper before the Thread 1 returns the Helper. Either way, the result is unwanted.
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper(); // <!-- Thread 2 creating new Helper
return helper; // <!-- Thread 1 returning Helper
}The code can also create interesting situations (deadlocks?) due to the synchronized(this) statement used in a ... creative way in this case.
I might be wrong of course. Just my �0.02.
Tuomas Rinta
Similar Messages
-
Double check locking using Volatile.
Hi gurus,
Please suggest if the following lazy loading would work.
public CommandFactory{
private static volatile ICommand command= null;
private static ICommand instanceCommand = null;
public static ICommand getCommand(){
if(instanceCommand == null){
synchronized(CommandFactory.class){
if(instanceCommand == null){
command = new Command();
instanceCommand = command;
return instanceCommand;
}For danny like "Boss of Talented people..lol...lmao....." understand
The Double checking with Volatile which would work with the new improved volatile contract.
public CommandFactory{
private static volatile ICommand command= null;
public static ICommand getCommand(){
if(command== null){
synchronized(CommandFactory.class){
if(command== null){
command = new Command();
return command;
}And the code I wrote which isn't any good as per JTahlborn is here
public class CommandFactory {
private static volatile ICommand command = null;
private static ICommand instanceCommand = null;
public static ICommand getCommand() {
if (instanceCommand == null) {
synchronized (CommandFactory.class) {
if (instanceCommand == null) {
command = new Command();
instanceCommand = command;
return instanceCommand;
} -
Hey everyone,
I posted a blog entry using Double-Checked Locking. Later one, Ryan commented to me that DCL does not work. See
http://jroller.com/page/davinci/?anchor=lazy_initialization_with_less_pain
I never knew that. Anyway, in a small efford to fix this I came up with the following code. Now one of the articles stated that many clever people already tried to fix the problem, and since I don't think I'm that smart, I guess this code also doesn't work. Can anyone explain to me why the following code could go wrong on some JVM's and platforms?
private class Singeton {
private static Singleton SINGLETON;
private static boolean initialized;
public static Singleton getInstance() {
if (!initialized) {
synchronized (Singleton.class) {
if (SINLETON == null) {
SINGLETON = new Singleton();
initialized = true;
return SINGLETON;
}Thanks,
VincentOkay, this migth seem like a load of... well, you
know, but in this case I force the JVM to initialize
the object before setting the boolean to true, or
not?Did you read the link I posted?
"The most obvious reason it doesn't work it that the writes that initialize the Helper object and the write to the helper field can be done or perceived out of order. Thus, a thread which invokes getHelper() could see a non-null reference to a helper object, but see the default values for fields of the helper object, rather than the values set in the constructor.
If the compiler inlines the call to the constructor, then the writes that initialize the object and the write to the helper field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or perform synchronization.
Even if the compiler does not reorder those writes, on a multiprocessor the processor or the memory system may reorder those writes, as perceived by a thread running on another processor. "
Your code still fails. There is no known solution to the problem (if you can't create the singleton during declaration time)
/Kaj -
A way to make double-checked locking work?
First a little background.
I am writing an application that will run in an websphere/db2 environment. This application needs to provide a lot of referential data to the UI to properly populate certain fields (on the order of several dozen reference data requests per page request with about 3-400 concurrent users). To prevent 20 sql statements for a single user clicking a single link, I implemented a dynamic caching scheme with double-checked locking, not realizing the potential danger.
After reading an article I found on the pitfalls of double-checked locking (http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-toolbox.html), I still would like to prevent synchronizing on every cache request. I think I've found a solution that transfers the weight to the write operations, as those would be much less frequent and can therefore take the bigger load. I would like to see if anyone can find a hole in this.
public class DCLTest {
private Resource rec = null;
boolean initializing = false;
public Resource getResource() {
Resource temp = null;
if (rec == null) {
synchronized (this) {
// initializing is now synchronized w/ main memory
if (initializing)
wait();
if (rec == null) {
// resource has lots of non-trivial datamembers that get initialized in the constructor
temp = new Resource();
initializing = true;
// If initializing is true, we know it's set by this thread,
// but still check that temp is valid
if (initializing && (temp != null)) {
synchronized (this) {
rec = temp;
initializing = false;
notifyAll();
}The first synchronize block establishes the first set of boundaries. When it completes, the initializing flag is raised and any other thread waiting to enter that block will see the flag and wait. Also, when the block is executed, all of the resource object's internal fields get written to the main memory, but the "global" pointer will still be null. Once we enter the second synchronized block, we update the global pointer and reset the flag. Since both synchronized blocks synchronize on "this", calling notifyAll won't resume execution of the threads that are waiting until they re-acquire the lock on this, or in other terms, until the second synchronized block completes. By that point the initializing flag will be false, the rec field will be not null and rec's data members will be in sync between all threads trying to access it.
This all depends on the assumption that the optimizer won't combine the two synchronized blocks. If that's the case, the two synchronized blocks assure that the reference to rec is written (and made visible to main memory) after the actual contents of rec are in main memory. Therefore, if a reading thread acquires a non-null value in the check outside the synchronized block, it will acquirea proper value. Otherwise, it'll get a null and will enter the synchronized block and all is well.
This logic seems too good to be true (which unfortunately means it probably is), but I can't find the hole. The only justification my gut can give this is the fact that the write operation becomes slower than if both read and write were synchronized, which is acceptable in my case.a big flaw (but easily solvable) is that there is no
guarentee that changes made to your "initializing"
variable
will ever be seen by other threads. It needs to be
marked volatile.this is not true. the JLS states that all threads are required to load from main memory on the first use of a variable in its lifetime. This would happen the first time a thread checks rec. When that check occurs, it will load from main memory and eihter get a null and enter the sync block, or get a valid reference and continue.
17.3 After a thread is created, it must perform an assign or load action
on a variable before performing a use or store action on that variable.
A second flaw is that you never set rec to anything
other then null.
( a single thread will enter the first synch block and
obtain a reference to temp. It will then NOT enter
the
second synch block as initializing is false. hence
your rec variable will be null)why is initializing false? it's set to true within the first block.
temp = new Resource();
initializing = true;
Third.
rec is null. The first thread enters the first synch
block and stops before changing the initializing
valriable. A
second thread then tries to enter the synch block. It
cannot get the monitor and therefore yeilds. The first
thread then continues inside the synch block. It just
leaves the first synch block before being stopped. The
second thread then resumes. It obtains the lock on the
first sych block. initilaizing is false so it skips
the
wait() statment. Rec is still null so the second
thread creates a new one. Now you have two threads
each has
a local reference to different Resource's. Which one
gets used? (actually at the moment niether would
get used cos of the previous problem)the whole idea of initializing is that it never gets written outside of a synchronized block. if a thread cuts in just as the first thread left the first sync block, initializing is set to true, so it will simply wait. This is to make sure that no one does anything while the thread that's initializing is in between the two sync blocks.
i think you overlooked where initializing is set to true in the first block -
Double Factory pattern purposal as replacement for Double Check #2
Hi All,
Here is the code for the pattern proposal, its intended as a replacement for double checked locking, which was proved to be broken in 2001. Here is the code...
public class DoubleFactory {
private static Object second_reference = null;
public static Object getInstance() {
Object toRet = second_reference;
if (toRet == null) {
second_reference = CreationFactory.createInstance();
toRet = second_reference;
return toRet;
private DoubleFactory() {}
public class CreationFactory {
private static Object instance = null;
public static synchronized Object createInstance() {
if (instance == null) {
instance = new Object();
return instance;
}Also I have spent several months discussing this with Peter Haggar, who believes that this code is not guaranteed to work. However I have been unable to discern from his message why he believes this will not be guaranteed to work, and I am posting this here to attempt to find a clearer explanation or confirmation that the pattern I am purposing (Double Factory) is guaranteed to work.
Thanks,
Scott
---------------------------- Original Message ----------------------------
Subject: Re: [Fwd: Double Factory replacement for Double Check #2] From:
"Scott Morgan" <[email protected]>
Date: Fri, January 25, 2008 10:36 pm
To: "Peter Haggar" <[email protected]>
Hi Peter,
I appologize if my last response came accross as rude or something. If
my code is not guaranteed to work ok, can you help me understand why. I
am after all looking for a solution for all of us.
If my solution is wrong as you say because the member variables of the
singleton are not up to date. I understand this to mean that the
second_reference pointer is assigned to the memory where the instance
object will get created before the instance object even starts the
creation process (when the jvm allocates memory and then enters the
constructor method of the Singleton). This doesn't seem possible to me.
Can you refrase your statments, to help me understand your points?
If not I am happy to turn to the original wiki for discussion.
Thanks for your effort,
Scott
Thanks for asking my opinion, many times, then telling me I'm
wrong...wonderful. You are a piece of work my friend. For what it'sworth, your email below shows you still don't understand these issues
or what I was saying in my emails. I've been more than patient.
>
All the best. And by the way, your code is not guaranteed to work. It's not just me that's "wrong", it's also the engineers at Sun who
designed Java, the JVM, and the memory model, and countless people who
have studied it. I'm glad you have it all figured out.
>
Peter
"Scott Morgan" <[email protected]>
01/18/2008 12:47 PM
Please respond to
[email protected]
To
Peter Haggar/Raleigh/IBM@IBMUS
cc
Subject
Re: [Fwd: Double Factory replacement for Double Check #2]
Hi Peter,
Thanks I understand your position now. However am I still believe that
it will work and be safe;
1) the Singleton you show would be fully constructed (having exited theSingleton() method) before the createInstance() method would have
returned.
2) The second_reference could not be assigned until the createInstance()
method returns.
3) So by the time second_reference points to Singleton all of the valueswill be set.
>
>
I do understand that if the createInstance method was not synchronized(at the CreationFactory class level) that my logic would be flawed, but
since there is synchronization on that method these points are true, and
your comments about up-to-date values are not accurate.
>
Cheers,
Scott
>In your listing from your latest email T2 does encounter a sync block
on createInstance.
>>>>
No. T2 will call getInstance and see second_reference as non-null.second_reference was made non-null by T1.
>>
>>>>
What are you exactly are you refering to with the phrase 'up-to-datevalues'?
>>>>
Assume my singleton ctor is thus:
public class Singleton
private int i;
private long l;
private String str;
public Singleton()
i = 5;
l = 10;
str = "Hello";
T2 will get a reference to the Singleton object. However, because youaccess second_reference without synchronization it may not see i as 5,
l as 10 and str as "Hello". It may see any of them as 0 or null. This
is not the out of order write problem, but is a general visibility
problem because you are accessing a variable without proper
synchronization.
>>
Peter
"Scott Morgan" <[email protected]>
01/16/2008 11:38 PM
Please respond to
[email protected]
To
Peter Haggar/Raleigh/IBM@IBMUS
cc
Subject
Re: [Fwd: Double Factory replacement for Double Check #2]
Hi Peter,
In your listing from your latest email T2 does encounter a sync blockon createInstance.
>>
What are you exactly are you refering to with the phrase 'up-to-datevalues'?
In this code the Singleton should also be
A) non mutable (as in the instance of class Object in the example).
If the singleton was more complex then the code to populate it'svalues
would go inside the sync of createInstance().
B) mutable with synchronization on it's mutator methods.
In your article you mention out of order writes, which doesn't occurin
this code.
Cheers,
Scott
You read it wrong.
- T1 calls getInstance which in turn calls createInstance.
- T1 constructs the singleton in createInstance and returns to
getInstance.
- T1 sets second_reference to the singleton returned in getInstance. -T1 goes about its business.
- T2 calls createInstance.
- T2 sees second_reference as non-null and returns it
- Since T2 accessed second_reference without sync, there is noguarantee
that T2 will see the up-to-date values for what this object refers to.
- Therefore the code is not guaranteed to work.
>>>
If this is not clear:
- Re-read my email below
- Re-read my article
- If still not clear, google on Double Checked Locking and readanything
from Brian Goetz or Bill Pugh.
Peter
"Scott Morgan" <[email protected]>
01/13/2008 05:26 AM
Please respond to
[email protected]
To
Peter Haggar/Raleigh/IBM@IBMUS
cc
Subject
Re: [Fwd: Double Factory replacement for Double Check #2]
Hi Peter,
Thanks for the reply, I don't see how T2 would see the a referenceto
a
partialy initialized object before the createInstance() method had
returned. If T1 was in createInstance() when T2 entered
getInstance(), T2 would wait on the CreationFactory's class monitor to
wait to enter createInstance().
Or in other words in the line of code ....
second_reference = CreationFactory.createInstance();
The pointer second_reference couldn't be assigned to the singleton
instance when the synchronized createInstance() had fully constructed,initialized and returned the singleton instance. Before that the the
second_reference pointer would always be assigned to null. So any
thread entering getInstance() before createInstance() had returned
(for the first time) would wait on the CreationFactory's class monitor
and enter the createInstance() method.
>>>
So T2 will wait for T1.
Cheers,
Scott
PS I think I am writing requirements for my next project :)
Sorry for the delay...been in all day meetings this week.
You are correct...I had been reading your code wrong, my apologies.
My explanations, although correct, did not exactly correspond to your
code.
However, the code is still not guaranteed to work. Here's why:
Assume T1 calls getInstance() which calls createInstance() and returnsthe
singelton. It then sets second_reference to refer to that singleton.
So
far, so good. Now, T2 executes and calls getInstance(). It can see
second_reference as non-null, so it simply returns it. But, there
was
no
synchronization in T2's code path. So there's no guarantee that even
if
T2 sees an up-to-date value for the reference, that it will seeup-to-date
values for anything else, ie what the object refers to...it's
instance data. If T2 used synchronization, it would ensure that it
read
up-to-date
values when it obtained the lock. Because it didn't, it could see
stale
values for the object's fields, which means it could see a partially
constructed object.
>>>>
In the typical double-checked locking, the mistake is to assume theworst
case is that two threads could race to initialize the object. But
the worst case is actually far worse -- that a thread uses an object
which
it
believes to be "fully baked" but which is in fact not.
Peter
"Scott Morgan" <[email protected]>
01/03/2008 06:33 PM
Please respond to
[email protected]
To
Peter Haggar/Raleigh/IBM@IBMUS
cc
Subject
Re: [Fwd: Double Factory replacement for Double Check #2]
Hi Peter,
Thanks for responding, I am still thinking that your mis
interpreting
the code so I have rewritten it here (Replacing
DoubleFactory.instance with DoubleFactory.second_reference for
clarity). If the T1 burps (gets interrupted) in the createInstance
method it wouldn't have returned so the second_reference pointer
would have never been
assigned
so T2 would just try again upon entering the getInstance method. Orif
it had already entered getInstance it would be waiting to enter
(until T1 releases the lock on CreationFactory.class ) on the
createInstance method.
>>>>
public class DoubleFactory {
private static Object second_reference = null;
public static Object getInstance() {
Object toRet = second_reference;
if (toRet == null) {
second_reference =
CreationFactory.createInstance();
toRet = second_reference;
return toRet;
private DoubleFactory() {}
public class CreationFactory {
private static Object instance = null;
public static synchronized Object createInstance() {
if (instance == null) {
instance = new Object();
return instance;
Does this clear up my idea at all?
second_reference should be always pointing to
null
or
a fully initialized Object
(also referenced by the pointer named 'instance' ), I don't see howit would end up partially initialized.
>>>>
Thanks Again,
Scott
"It" refers to T2.
Your createInstance method is identical to my Listing 2 and is fine
and
will work.
Yes, the problem with your code is in getInstance.
>I don't see how the DoubleFactory getInstance method could bereturning
a partially initialized object at this point. If CreationFactoryalways
returns a fully initialized object and DoubleFactory only assigns a
new
reference/pointer to it how could DoubleFactory getInstance return a
reference/pointer to partially initialized object?
>>>>>>>
>>>>>
The reason it is not guaranteed to work is explained in my previousemails
and in detail in the article. However, I'll try again. Anytime you
access shared variables from multiple threads without proper
synchronization, your code is not guaranteed to work. Threads are
allowed
to keep private working memory separate from main memory. There are
2
distinct points where private working memory is reconciled with main
memory:
- When using a synchronized method or block - on acquisition of thelock
and when it is released.
- If the variable is declared volatile - on each read or write of
that
volatile variable. (Note, this was broken in pre 1.5 JVMs which isthe
reason for the caveat I previously mentioned)
Your createInstance method uses synchronization, therefore, the
reconciliation happens on lock acquisition and lock release. T1 can
acquire the lock in createInstance, make some updates (ie create an
object, run it's ctor etc), but then get interrupted before exiting
createInstance and therefore before releasing the lock. Therefore,
T1
has
not released the lock and reconciled its private working memory withmain
memory. Therefore, you have ZERO guarantee about the state of mainmemory
from another threads perspective. Now, T2 comes along and accesses
"instance" from main memory in your getInstance method. What will
T2
see?
Since it is not properly synchronized, you cannot guarantee that T2sees
the values that T1 is working with since T1 may not have completely
flushed its private working memory back to main memory. Maybe it
did completely flush it, maybe it didn't. Since T1 still hold the
lock,
you
cannot guarantee what has transpired. Maybe your JVM is not usingprivate
working memory. However, maybe the JVM your code runs on does or
will
some day.
Bottom line: Your code is not properly synchronized and is notguaranteed
to work. I hope this helps.
Peter
"Scott Morgan" <[email protected]>
01/03/2008 12:49 PM
Please respond to
[email protected]
To
Peter Haggar/Raleigh/IBM@IBMUS
cc
Subject
Re: [Fwd: Double Factory replacement for Double Check #2]
Hi Peter,
Thanks for your response, I don't follow what 'it' refers to in
the
phrase 'It can see'. So for the same reason that you state that
example 2 from your article I believe this class CreationFactory to
work flawlessly when a client object calls the createInstance
method.
>>>>>
I see this CreationFactory code as identical to your example 2 doyou agree with this?
>>>>>
public class CreationFactory {
private static Object instance = null;
public static synchronized Object createInstance() {
if (instance == null) {
instance = new Object();
return instance;
}Then my rational in the DoubleFactory class is that it can obtain a
reference/pointer to the fully initialized object returned bycalling the above code. I believe you think that the problem with
my code is
in
the DoubleFactorys getInstance method, is this correct?
I don't see how the DoubleFactory getInstance method could bereturning
a partially initialized object at this point. If CreationFactory
always
returns a fully initialized object and DoubleFactory only assigns a
new
reference/pointer to it how could DoubleFactory getInstance return a
reference/pointer to partially initialized object?
>>>>>
Thanks again,
Scott
public static synchronized Singleton getInstance() //0
if (instance == null) //1
instance = new Singleton(); //2
return instance; //3
This above code is fine and will work flawlessly.
Annotating my paragraph:
T1 calls getInstance() and obtains the class lock at //0. T1 "sees"
instance as null at //1 and therefore executes: instance = new
Singleton() at //2. Now, instance = new Singleton() is made up of
several lines of non-atomic code. Therefore, T1 could be
interrupted
after Singleton is created but before Singleton's ctor isrun...somewhere
before all of //2 completes. T1 could also be interrupted after
//2 completes, but before exiting the method at //3. Since T1 has
not
exited
its synchronized block it has not flushed its cache. Now assume T2
then
calls getInstance().
All still true to this point. However, with your code the nextparagraph
is possible, with the code above, it's not. The reason is that T2
would
never enter getInstance() above at //0 because T1 holds the lock. T2will
block until T1 exits and flushes it's cache. Therefore, the code
above
is
properly thread safe.
It can "see" instance to be non-null and thus
return it. It will return a valid object, but one in which its ctor
has
not yet run or an object whose
values have not all been fully flushed since T1 has not exited itssync
block.
"Scott Morgan" <[email protected]>
01/02/2008 06:10 PM
Please respond to
[email protected]
To
Peter Haggar/Raleigh/IBM@IBMUS
cc
Subject
Re: [Fwd: Double Factory replacement for Double Check #2]
Hi Peter,
Thanks for the response I understand the rational for inventing
the
double check anti pattern, I am sorry I still don't understand the
difference between your solution #2 and my CreationFactory class.
>>>>>>
From your article figure 2.public static synchronized Singleton getInstance() //0
if (instance == null) //1
instance = new Singleton(); //2
return instance; //3
If I understand your email correctly this figure 2 is also flawed,since...
>>>>>>
T1 calls getInstance() and obtains the class lock at //0. T1 "sees"
instance as null at //1 and therefore executes: instance = new
Singleton() at //2. Now, instance = new Singleton() is made up ofseveral lines of non-atomic code. Therefore, T1 could be
interrupted
after Singleton is created but before Singleton's ctor isrun...somewhere
before all of //2 completes. T1 could also be interrupted after
//2 completes, but before exiting the method at //3. Since T1 has
not
exited
its synchronized block it has not flushed its cache. Now assume T2
then
calls getInstance(). It can "see" instance to be non-null and thus
return it. It will return a valid object, but one in which its
ctor
has
not yet run or an object whose
values have not all been fully flushed since T1 has not exited itssync
block.
So is #2 is also flawed for this reason?
If so please revise your article, since I interpreted #2 as a
plausible
solution recommended by you (which lead me to the DoubleFactory
idea).
If not please help me understand the difference between #2 and my
CreationFactory class.
>>>>>>
Thanks,
Scott
#2 is in Listing 2 in the article. What I meant was to forget the
DCL
idiom, and just synchronize the method...that's what listing 2
shows.
DCL
was invented to attempt to get rid of the synchronization for 99.9%
of
the
accesses.
The solution I outlined in my email is using the DCL idiom, but on
a
1.5
or later JVM and using volatile.
You solution is not guaranteed to work. Here's why:
public class DoubleFactory {
private static Object instance = null;
public static Object getInstance() {
Object toRet = instance;
if (toRet == null) {
instance =
CreationFactory.createInstance();
toRet = instance;
return toRet;
private DoubleFactory() {}
public class CreationFactory {
private static Object instance = null;
public static synchronized ObjectcreateInstance()
//1
if (instance == null) {
instance = new Object(); //2
return instance;
} //3
}T1 calls createInstance() and obtains the class lock at //1. T1"sees"
instance as null and therefore executes: instance = new Object() at//2.
Now, instance = new Object() is made up of several lines of
non-atomic
code. Therefore, T1 could be interrupted after Object is created
but
before Object's ctor is run...somewhere before all of //2
completes.
T1
could also be interrupted after //2 completes, but before exiting
the
method at //3. Since T1 has not exited its synchronized block ithas
not
flushed its cache. Now assume T2 then calls getInstance(). It can"see"
instance to be non-null and thus return it. It will return a
valid object, but one in which its ctor has not yet run or an
object
whose
values have not all been fully flushed since T1 has not exited itssync
block.
The bottom line is that if you are accessing shared variables
between
multiple threads without proper protection, you are open for aproblem.
Proper protection is defined as: proper synchronization pre 1.5,
and
proper synchronization or proper use of volatile 1.5 or after.
Therefore, if you must use the DCL idiom you have one option: -
Use DCL with volatile on a 1.5 or later JVM.
>>>>>>>
You can also forget about DCL and just use synchronization (listing2
in
my article) or use a static field (listing 10 in my article).
I hope this clears it up.
Peter
"Scott Morgan" <[email protected]>
01/02/2008 04:00 PM
Please respond to
[email protected]
To
Peter Haggar/Raleigh/IBM@IBMUS
cc
Subject
Re: [Fwd: Double Factory replacement for Double Check #2]
Hi Peter,
I apologies for not understanding but I don't see what is
different
between the solution you purposed...
2) Don't use DCL but use synchronization
and the code that I am putting forward. Perhaps I do just notunderstand
but you seem to be contradicting yourself in this email?
I understand that you are saying in #2 that this will always 'work'
with
out any issues...
public static Object instance = null;
public static synchronized Object getInstance() {
if (instance == null) {
instance = new Object();
return instance;
But first you seem to say in the email that if T1 gets
interrupted
it
may leave the instance pointing to a partially initialized object?
So as far as I understand it the createInstance method in my
CreationFactory class should be successful (always retuning a
fully initialized object) for the same reason #2 is successful.
Please keep in mind that there are two different instancepointers
in
the code I sent you, one is part of the DoubleFactory class and
the other is part of the CreationFactory class.
>>>>>>>
Thanks for your time, just looking for better solutions!
Scott
Scott,
Your solution is not guaranteed to work for various reasons
outlined
in
the article. For example, you can still return from your code apartially
initialized object. This can occur if T1 gets interrupted beforeleaving
the synchronized method createInstance() and T2 calls
getInstance().
T2
can "see" toRet/instance as non-null but partially initialized
since
T1
has not fully flushed its values.
As of 1.5, Sun fixed various issues with the memory model that
were
broken. Double Checked Locking will still break unless you usevolatile
(which was fixed in 1.5). Therefore, the following code works:
volatile Helper helper;
Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
return helper;
but the original DCL idiom will not work. So, your options are:
1) Use DCL with volatile (above)
2) Don't use DCL but use synchronization
3) Don't use DCL, but use a static field.
#2 and #3 are outlined in my article from 2002.
Hope this helps,
Peter
"Scott Morgan" <[email protected]>
12/26/2007 04:12 PM
Please respond to
[email protected]
To
Peter Haggar/Raleigh/IBM@IBMUS
cc
Subject
[Fwd: Double Factory replacement for Double Check #2]
Hi Peter,
Thanks for the article on the out of order write problem. Whatdo
you
think of this as a solution?
TIA,
Scott
---------------------------- Original Message----------------------------
Subject: Double Factory replacement for Double Check #2
From: "Scott Morgan" <[email protected]>
Date: Wed, December 26, 2007 2:55 pm
To: [email protected]
Hi Ward,
Here is a pattern submission
Double Factory
Lazy initialization of singletons in accepted for a while usingthe
double check pattern. However it has been discovered that the
double
check pattern isn't thread safe because of the out of order write
problem. This problem occurs when Threads entering the Singleton
Factory method return with a fully constructed, but partially
initialized, Singleton object.
>>>>>>>>
Therefore: It makes sense to look for a way to initializeSingletons
in
a Lazy and Thread Safe manor. The following illustrates a fairly
simple
solution...
package foo;
public class DoubleFactory {
private static Object instance = null;
public static Object getInstance() {
Object toRet = instance;
if (toRet == null) {
instance =
CreationFactory.createInstance();
toRet = instance;
return toRet;
private DoubleFactory() {}
public class CreationFactory {
private static Object instance = null;
public static synchronized ObjectcreateInstance()
if (instance == null) {
instance = new Object();
return instance;
This gets around the out of order write problem because all
Threads
waiting on the CreationFactory's Class monitor will have a fully
constructed and initialized instance when they actually exit the
createInstance method.
>>>>>>>>
>>>>>>>>
During runtime while the Singleton instance is getting created(constructed and initialized) there may be a few Threads waiting
on
the
CreationFactory Class's objects monitor. After that period all
the
Treads
accessing
the Singleton will have unsynchronized reads to the instance,
which
will
optimize execution.
References:
http://www.ibm.com/developerworks/java/library/j-dcl.html
Copyright 2007 Adligo Inc.Scott-Morgan wrote:
Hi All,
Thanks for your comments, here are some more....
jtahlborn you state that
the only way to guarantee that a (non-final) reference assignment is visible across threads is through the use of volatile and synchronized,
From the jvm spec
http://java.sun.com/docs/books/jls/third_edition/html/memory.html
17.4.1 Shared Variables
Memory that can be shared between threads is called shared memory or heap memory.
All instance fields, static fields and array elements are stored in heap memory.
Since both the second_reference and instance fields are both static, they are shared and visible across all threads.Yes, all these things are shared across threads, however, if you keep reading, there is a notion of "correct" sharing. obviously these values may be visible, that's why double-checked locking was used for so long before people realized it was broken. it worked most of the time, except when it didn't, and that's what i'm trying to show. that the only way to correctly share state between threads is via synchronization points, the most common being volatile and synchronized (there are a couple of other less used ones which don't apply here). The articles you linked to below from ibm cover the "visibility" in great depth, this is exactly what i am referring to.
You also state that volatile is a solution, but you seem to rebut your self in stating that the overhead for volatile is almost as great as synchronization.
This article illustrates the solution, and also comments on the overhead of volatile.
http://www.ibm.com/developerworks/library/j-jtp03304/
linked from
http://www.ibm.com/developerworks/java/library/j-dcl.html
volatile is a solution, in that it is correct, and you avoid the appearance of synchronization each time. however, since the semantics of volatile were strengthened in the new memory model, using volatile will perform practically (if not exactly) the same as simply synchronizing each time. the article you link to says exactly this under the heading "Does this fix the double-checked locking problem?".
Also could you be more specific about the example at the end of the jvm memory spec page, like a section number?It's the very last thing on the page, the "discussion" under 17.9, where it mentions that changes to "this.done" made by other threads may never be visible to the current thread. -
I have upgraded to an Iphone 6 and am at IOS 8.2. My calendar alerts no longer show up as notifications on my phone. I have gone into settings and double checked that notifications for calendar was on and it is. Any ideas on a fix?
I have iPhone 4s but the same problem with calendar on 8.2 iOS - no sound, no notification appears - but everything is switched on.
-
I have just bought four songs from iTunes store using my iMac. I can play the music on my iMac and throughout my Apple TV. However after several restarts and double checks I can't get the four tunes to sync with either my iPhone or my iPad. All the software is up to date.
do you use the same Apple ID on your iMac, your iPhone and iPad? This is a requirement.
-
my email is saying cant send as the username or password is wrong, i have double checked and its excactly the same as what i use on my computer.
I found the answer guys it was mysmpt.live.com the password was not the same whoo hoo
-
i have even double checked the album and the album has the EDITED pic but for some reason when uploaded or sent the original is what goes thru... makes me very irritated! not sure if its a setting or some bug... any suggestions???
I think it depends on how you share it. Sometimes when I email it to myself it retains the edits, but I read that when people sync their phone it sometimes does not.
-
I did a backup from all my files saved in old external hd to time capsule. After that double checked and recover one file from TC to mac air and it worked just perfect. Today went through TC to recover another file and none of them were there?Anybody has a clue what happened?
renatocremonese wrote:
I want to use it for backing up my Mac.
It's good for that . . .
But also I don't keep all my stuff in my Mac.
But not for that.
This older and not day-by-day usage files I want to store in the time machine.
You can do that (see below), but how are you going to back them up? If your only copies are on the TC, when (not if) it fails, you risk losing your only copy of the data.
Is it possible to split TC in two partitions.
No, but there are some workarounds, including making a fixed-size disk image on it to "reserve" some space. See #Q3 in Using Time Machine with a Time Capsule.
But you still won't have backups of the stuff you put there.
You don't say what kind of Mac you have. If it's a desktop model, just keep the external HD connected to it, and let Time Machine back it up along with your internal HD.
However, it sounds like you may have a laptop, where that's not going to be convenient. In that case, your best bet might be to copy the external HD to a disk image on the TC as above, then keep the HD in a safe place.
To finish, when i enter the TC and go through the Time line how can I get a file from there and move it back to Mac hd.
Via the "Star Wars" display, per #15 in Time Machine - Frequently Asked Questions.
You might also want to review the Time Machine Tutorial, and perhaps browse the rest of the FAQ. -
Itunes won't connect, status bar goes about half way and stops, then times out. I have tried all fixes posted, you name it, I have done it. Running Vista and current version of Itunes. Can connect to Internet with any other app. Using Firefox, their latest version if that matters.
I have seen this is an on going problem throughout the Itunes community. All I can say is 'Bad Form Apple, Bad form.'One more odd thing. The itunes diagnostics believes my windows firewall is on which is it not (believe me I've checked/double checked etc) AND believes itunes is not enable in windows firewall which it is, if ever I turned WF on. How can itunes get this wrong? I mean, if itunes believes its being blocked, maybe that's why I'm being blocked...has anyone heard of this?
-
Error 0x00000709 operation could not be compleated Double check the printer name etc.
After installing my new printer and removing all other printers from my computer I now can not make the only printer listed as my default printer. I get this error 0X00000709 operation could not be completed Double check the printer name and make sure it is connected. I have done all that over and over again. I also I have reinstalled the old printer software and tried to default to my new printer at that time and still the same error. I have checked my register and it has the old printer listed but does not allow me to change it. I now have removed all but the new printer from my computer but I still can not make it my default printer. Programs such as Adobe only recognizes the default printer (which is not there any more) and don't even list the new printer as an option. The printer works just fine accept with the programs that uses the default printer. The Windows Hardware and Device Troubleshooting finds the problem (printer not set as default)but can not fix it.
I sure wish someone out there could help me get rid of the error and allow me to default my printer again. I have noticed other people have had this same issue with error 0X00000709 using other Windows versions as well. I have been trying to resolve this issue for the past three months and would appreciate any and all ideas.
I have an HP Pavilion elite HPE 337C computer running with Window 7 and I installed my new HP LaserJet PRO CM1415fnw color MFP printer. My old printer that I removed (but is still listed in my Regester) was an HP 6500 inkJet.After doing some research on the net:
This link provided an answer:
https://exploreb2b.com/articles/solving-error-0x00000709-cant-set-default-printer-problem
Regedit -> HKEY_CURRENT_USER -> Software->Microsoft->Windows NT->Current Version->Windows
One of the entries you should see in the right hand pane is“Device”. If the value for “Device” as noted under the “Data” area is anything other than the printer you are using, then highlight “Device” in the right hand pane with the mouse and press the delete key to remove it. (I edited it and put the name of the printer I wanted to be the default)
VI. Restart the computer so it starts with the altered Windows system registry. (Italics mine) -
Regd. error in sender agreement(when to check sender uses virtual receiver)
hi Experts,
I am doing a file( SFTP adapter ) to IDOC scenario.
I got an error :
Couldn't retrieve inbound binding for the given P/S/A values:FP=XYZ;TP=;FS=XXXX;TS=XXXX;AN=XXXXXX;ANS=;
I checked my sender agreement and saw some "*" symbol displayed at the end on SA name.
To quick fix it and remove the star symbol'', i have just created SAgreement again and this time i checked "Sender uses virtual receiver " and revomved thestar symbol '' and saved without mentioning anything there.
When i tested it worked! but i want to know what made it work, is it the right practice.
i did a lilttle search on when to use "sender uses virtual receiver" option.i came to an understanding that it is mainly used to handle multiple input file formats in a single configuration scenario.
one more qns:
What are marketplace adapters,is this error comes when we use adapters which are not inbuilt or bought from external vender.
Regards,
Anika
Edited by: Anika Gulati on Jun 10, 2009 1:23 PMHere are few ways for it...
SAP Process Integration: When to Use u201CSender Uses Virtual Receiveru201D in a Sender Agreement
https://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/40cb67f7-6464-2b10-bcb9-8edb9a3569f9
SAP Network Blog: Virtual Receiver - Why do you 'really' need it?
/people/shabarish.vijayakumar/blog/2008/09/16/virtual-receiver--why-do-you-really-need-it
-SM -
Check mapping used in BIC module
Hello gurus
we have an EDI scenario. modules are used in the EDI receiver communication channels.
Following is the processing sequence and module configuration of one of the channels :-
Processing sequence:
1 localejbs/Seeburger/solution/sftp Local Enterprise Bean solutionid
2 localejbs/CallBicXIRaBean Local Enterprise Bean bic
3 localejbs/ModuleProcessorExitBean Local Enterprise Bean exit
Module Configuration:
bic LogAttID ConverterLog
bic destEncoding ISO-8859-1
bic destTargetMsg MainDocument
bic mappingName See_X2E_DESADV_UN_D93A
bic srcEncoding ISO-8859-1
bic srcTargetMsg MainDocument
exit JNDIName deployedAdapters/SeeXISFTP/shareable/SeeXISFTP
Is it possible to get the mapping that is used here i.e See_X2E_DESADV_UN_D93A to view or edit?
I am new to BIC and BIC MD. I went through the documents that are available for mapping designer but i am now even more confused.
The mapping designer can be used to output .xsd file which can be imported into the ESR as external definition and then graphically mapped to the IDoc. Then what is the purpose of this mapping separately and where can i find it??
Appreciate any help coming my way.
Regards,
XineohpiHi Iphoenix
The XSD file should be imported into ESR as an External Definition, so that it can be used as a source/target for graphical message mapping.
As for the BIC mapping, this is deployed as an SCA file into the PI system. This is normally done via JSPM by the Basis team.
Normally, if your partner is using X12 or EDIFACT, you might not need to change anything with BIC mapping. Only in cases where your partner's X12/EDIFACT definition deviates from the international standard, then you might need to adjust the BIC mapping accordingly using BIC MD.
In the case where the standard is used, you just need to double check that Seeburger already provides that XML to EDI conversion mapping, and that it has been deployed by your Basis team (you can check in the Seeburger Workbench to see what has been deployed.) Once the BIC mapping is there, you use that mapping in the BIC module configuration.
To summarize, for an IDoc to standard EDI interface, your main development/configuration effort would be:-
i) Create graphical mapping from IDoc to EDI (XML format)
ii) Configure communication channel to use BIC mapping for X2E conversion.
Rgds
Eng Swee -
Fixed Vendor check box with BAPI "BAPI_SOURCEDETERMIN_GETSOS"
Hello gurus,
I am new to BAPI & I need to update the source list(ME01) with agreement no., item, unit & fixed vendor check-box.
My question to all that the fixed vendor check box will be checked or not if i use the BAPI BAPI_SOURCEDETERMIN_GETSOS?
Thanks & regards,
FeludaHello,
The coding you've made regarding the check/uncheck seems fine...
However, check again logic-atp_wrkmod...
As far as i've seen, the allowed values are space and 'A' .
The value 'X' is not in the domain range.
Hope it helps!!
Maybe you are looking for
-
SharePoint - Automated Active Directory User Management
We are currently using a custom list to capture data from our HR team related to Employee Changes such as New Hires, Change of Information, and Exits. The next step after the form is filled out is to make the AD/Exchange change for that request. I'
-
Intercompany STO - PO not showing in VL10B
Dear all, In my company I have an intercompany STO between 2 plants A and B. However, when I try to run transaction VL10B, the PO is now showing. To solve the problem I tried to remove the dates and shipping point in VL10B without sucess. I have chec
-
Hi All, In my report, when there is more than one item for a Purchase order, it is bringing the total quantity. The requirement is for each PO item, its GR quantity should be printed. How to calculte GR quantity for a particular purchase order item?
-
We have five in house built applications that run on the same server. However, one application seems to be timing out lately. Different pages, different hours of the day, different states (from CA, to TX, to MS, to FL), etc. Whenever one of the pages
-
ASCII character/string processing and performance - char[] versus String?
Hello everyone I am relative novice to Java, I have procedural C programming background. I am reading many very large (many GB) comma/double-quote separated ASCII CSV text files and performing various kinds of pre-processing on them, prior to loading