• Home
  • RSS Feed
  • Log in

Spring and visibility problems
Posted by Peter Veentjer around lunchtime: March 1st, 2007

Spring is a great framework, but I expect that some Spring based applications are subject to visibility problems (a type of concurrency problem). This blog entry describes the cause and effects of this problem, and also how it can be solved.

Visibility problems

Most programmers don't have much experience with multi threading and have a very simplistic view on reality: if a thread makes a change to a variable, this change is directly visible to all other threads that access the same variable. This view is called sequential consistency, but the problem is that no virtual machine automatically provides this view.

The reason for this apparently faulty behavior is performance. Most variables are not shared between threads, so no special instructions (memory barriers) have to be added to make the program sequentially consistent. If these instructions were automatically added to all variable accesses, it would greatly reduce performance because a lot of optimizations would be excluded from being used. To name a few:

  1. usage of super fast local-memory (like caches and cpu-registers). It also could reduce the performance benefits of multi-core systems because the increased access to main memory would become the bottleneck.
  2. reordering of instructions to increase the chance of a cache hit.

The consequence of a visibility problem, is that a value written to a variable by one thread, doesn't have to be visible in other threads (maybe never). This could lead to an easy to detect NullPointerException, but it can also lead to much harder to detect problems like shown in the following example:

public class SomeRunnable implements Runnable{
    private boolean stop = false;

    public void stop(){
        stop = true;
    }

    public void run(){
        while(!stop){
                System.out.println("hello");
        }
    }
}

There are a few reasons why this runnable could fail to stop:

  1. stop is not safely published: the thread that executed the run method, doesn't need to see a change in the stop value. A possible scenario would be: thread1 (the thread that executed run) is running on cpu1 (with cache1). Thread2 (the thread that calls stop) is running on cpu2 (with cache2). When thread1 runs, it needs the value of stop, sees the initial false value and places it in his cache. When thread2 executes stop, stop is set to true. But it might happen that this value remains in cache2 for an undetermined time and isn't flushed to main memory, so thread1 never sees the new value when it happens to read from main memory. Even if the value is flushed to main memory, thread1 could still be reading the stale value from cache1.
  2. because the access to the stop variable isn't safely published, and the value doesn't change in the loop, the 'compiler' (JIT, cpu etc) could decide to replace the variable read by the constant 'true' in that loop.

Visibility problems can lead to hard to detect errors and unpredictable behavior, and you definitely want to keep them out of your system. And although most cpu's are not subject to visibility problems (because of strong Memory Coherence), betting on this behavior is asking for problems (the application also wouldn't be platform independent).

Spring applications and visibility problems

I expect that a lot of Spring applications are subject to visibility problems. If you look at singleton beans for example (dao's, controllers, managers etc), these beans often are shared by many threads, to name a few:

  • threads from the servlet container
  • threads from remoting middleware
  • threads from jmx
  • threads from triggers or other internal threads

Take a look at the following example:

public class EmployeeManagerImpl implements EmployeeManager{

    private EmployeeDao employeeDao;

    public setEmployeeDao(EmployeeDao employeeDao){
        this.employeeDao = employeeDao;
    }

    public void fire(long employeeId){
        Employee employee = employeeDao.load(employeeId);
        employee.fire();
    }
}

And the bean configuration that belongs to it:

    <bean id="employeeManager" class="EmployeeManagerImpl">
        <property name="employeeDao" ref="employeeDao"/>
    </bean>

The visibility problem here, is that employeeDao, set by the thread that constructed the employeeManager, isn't safely published and doesn't have to be visible in other threads. If one of those threads calls the fire method on the EmployeeManagerImpl, it could lead to a NullPointerException because that thread still sees a null value for the employeeDao.

The problem can be solved in a few ways:

  1. make employeeDao volatile. Although it sounds quite strange, because the employeeDao is not going to change after it has been set, volatile variables are always safely published. Personally I don't like this solution much because it is misleading (the value is never going to change after the object has been constructed) and it also reduces performance (the variable always has to be read from main memory instead of local memory).
  2. make employeeDao final, because final variables also are safely published. The problem with final variables is that they only can be set by constructor based Dependency Injection (DI) and Spring promotes setter based DI. Personally I prefer constructor based DI, because it is a lot easier to guarantee class invariants. Although those setters only are visible in an implementing class, and not in the interface, I still don't feel happy about because it also makes classes harder to understand. But constructor based DI isn't perfect either; I guess most of us have struggled with large constructors.

Problem not that bad?

Before going into detail why the problems maybe are not that bad, I need to explain the new Memory Model found in Java 5 and higher (JSR-133) (see footnote). The model describes under what kinds of conditions a variable will be visible in other threads and it also shields you from reasoning about caches (they are not mentioned in the Java Memory Model).

The model is expressed in terms of actions:

  1. read/writes to normal/volatile/final variables
  2. lock acquire/release
  3. thread start/join

The model also contains a set of happens-before rules between actions. If a happens-before rule applies between action1 and action2, then all changes made by action1 are visible in action2. Examples of happens-before rules are:

  1. Program Order rule: each action in a thread happens-before every action in that thread that comes later in the program order. It is important to realize that normal variable reads/writes, can be reordered as long as they keep the 'within-thread as-if-serial semantics': the reordering should not be visible inside the thread.
  2. Volatile variable rule: a write to a volatile variable happens-before every subsequent read of that same variable (that is why making the employeeDao volatile works).
  3. Monitor lock rule: an unlock on a monitor lock happens-before every subsequent lock on that same monitor lock. (The same goes for the the new Lock found in Java 5.
  4. Transitivity rule: if action1 happens-before action2, and action2 happens-before action3, then action1 happens-before action3.

If there is a happens before relation between the write and the read of a variable, then it is safely published.

Safe handoff

These happens-before rules can be used to check if there is a happens-before relation between two actions. Take a look at the following example:

int a=0;
volatile boolean b=0;

void initialize(){
        a=console.readInteger();
        b=console.readBoolean();
}

void print(){
        print(b);
        print(a);
}

A possible ordering of actions could be:

action thread 1 thread 2
action1 normalwrite(a)
action2 volatilewrite(b)
action3 volatileread(b)
action4 normalread(a)

Because action1 happens-before action2 (program order) and because action2 happens-before action3 (volatile variable rule) and because action3 happens before action4 (program order), action1 happens before action4 (remember that the happens before rules are transitive). This means that the change in action1, is visible in action4. This technique is called 'safe handoff' (aka 'piggybacking on synchronization').
Safe handoff uses the safe publication of a variable X (in this case b), to safely publish all unsafely-published-variables that are changed before X (in this case a).

Safe handoff in Spring

The Spring applicationcontext also provides safe handoff (only in Java 5 and higher): after a singleton bean is created, it is placed in a singletonmap. When it is needed, it is retrieved from that map. But instead of using the 'volatile variable' rule, it uses the 'monitor lock' rule (action4 and action5)

The following table shows a very simplified ordering of actions (variable mapentry.ref is the variable 'X' from the 'save handoff' technique):

action thread 1 thread 2
action1 lock(singletonmap)
construction of the employeeManager
action2 normalwrite(employeeDao)
employeeManager is placed in the applicationcontext
action3 normalwrite(mapentry.ref)
action4 unlock(singletonmap)
employeeManager is read from the applicationcontext
action5 lock(singletonmap)
action6 normalread(mapentry.ref)
action7 unlock(singletonmap)
employeeManager fire method is called
action8 normalread(employeeDao)

This means that there is a happens before relation between action2 and action8, so the value set in the employeeDao (action2), is visible when it is read by another thread (action8). That is why standard Spring singletons don't have visibility problems. If you want to see it for yourself, check out the DefaultSingletonBeanRegistry and the 'public Object getSingleton(String beanName, ObjectFactory singletonFactory)' method

Conclusion

I'm glad that standard singleton beans aren't subject to visibility problems (under Java 5 and higher), but I don't think it is the correct way to deal with concurrency control in Spring (or in general):

  1. objects can't be safely used in a different environment. So your objects are tied to the (current version of the) Spring framework to make them work correct.
  2. the save handoff behavior is not guaranteed by Spring, and it only works under Java 5 and higher. The behavior is undefined in older JVM's.
  3. are beans with different scopes than singletons free from visibility problems?

I don't want to depict Spring as a bad product: it really is amazing and I'm always happy when I can use it on a project. But I do think that developers should be more careful when writing code that is used in a multi threaded environment.

A part of this responsibility should be taken bij developers themselves, if you write threadsafe code, you need to know what you are doing. But I also think the guys behind Spring should take part of this responsibility: not all developers have a lot of experience with writing multi-threaded code and I guess most don't know anything about the Java Memory Model. If these issues are not mentioned in the Spring documentation, a lot of developers will remain agnostic and this is going to lead to problems in the future.

Footnote:
If you want a more in depth explanation of the new Java Memory Model, I suggest 'Java Concurrency in Practice' from Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes and Doug Lea, or check out the following website The Java Memory Model

I want to thank colleagues, acquaintances and the guys from the concurrency mailing list for proofreading this post.

  • Share/Bookmark

Filed under Concurrency Control, Java, Spring | 4 Comments »



4 Responses to “Spring and visibility problems”



    Indrit Selimi Says:
    Posted at: March 13, 2007 at 2:09 pm

    Please stop describing multi-threading
    programming as ’something that only aliens knows how to use… ‘

    And stop also speak about Spring as something that has a lot of problems, we are using spring in our E-commerce web site from different years and we haven’t yet any concurrency problem!



    Peter Veentjer Says:
    Posted at: March 14, 2007 at 9:02 am

    Hi Indrit, thank you for your reply

    As far as I know I didn’t depict Spring as a bad framework (a framework with a lot of problems), so I don’t understand how you come to that conclusion.

    And multi-threading has a lot of complicated facets not a lot of people know about, for example the memory model or the difference between the memory models before and after jsr133. If you don’t know about these issues, concurrent programming is a lucky guess at best.

    Did you read the complete article?



    DarrenWang Says:
    Posted at: April 20, 2009 at 10:41 am

    Good article indeed, concurrency and multi-threadings are not easy, if you can’t fully understand that, as Peter says, U r just lucky,hehe

    I am a big funs of spring, but i don’t think the article is blaming or denigrating it. :-)



    Matt Says:
    Posted at: December 9, 2009 at 8:35 am

    Interesting article, thanks



Leave a Reply

Click here to cancel reply.

Deployment automation for Java application running on Websphere, WebLogic and JBoss

Archives

  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009

Xebia Sites

  • Xebia Corporate
  • Xebia France
  • Xebia India

Categories

  • Java (279)
  • Agile (109)
  • General (50)
  • Testing (42)
  • Performance (42)
  • Hibernate (36)
  • Scrum (33)
  • Podcast (31)
  • Architecture (31)
  • Spring (28)
  • SOA (24)
  • Maven (22)
  • Project Management (22)
  • Flex (17)
  • JPA (17)
    • JPA implementation patterns (13)
  • Eclipse (15)
  • Quality Assurance (14)
  • Middleware (19)
  • Frameworks (13)

Tag Cloud

    Maven Semantic Web Java esb XML Poppendieck Spring Hibernate Agile Awareness Workshop JavaOne Groovy Grails Functional Programming Scala fitnesse IntelliJ Agile Closures Xebia SOA Performance qcon Architecture Introduction to Agile Scrum Testing Ajax Seam Lean product owner
medicin depression buy phentermine without a perscription aricept generic hair loss help how do you prevent bone loss urinary tract infection symptoms viagra sex domination cialis viagra cures for throat infection buy sumycin acne care new medication for cancer treatment help for sleeping problems on-line pharmacies cure snoring medications to help clot blood what is aspirin buy zestoretic bronchitis vs pneumonia back pain muscle acne face medication muscle women pain behind knee fat blocker man health arthritis natural cure woman health women insomnia cheap phentermine online cats and irritable bowel syndrome buy cialis generic online nutritional diet for osteoporosis abnormal blood clots treatments for hair loss what is zyprexa dental whitening products impotence herbs drugs for diabetes allergy prevention buy canada levitra Mentax adhd in children hair loss in woman medicines for blood clot online imitrex viagra buy free dog products clindamycin drug how to stop hair loss chloramphenicol discount drug viagra what valium does permanent hair loss heart failure medicine avapro 150mg ordering viagra online food allergies order viagra online online viagra prescription carisoprodol mg improve your skin discount erectile dysfunction medication buy xanax online buy order viagra scabies teatments information allegra vitamine b1 diazepam breast cancer support free stop smoking cipro side effects ultram cheapest treatment attention deficit disorder discount vitamins supplements how to get viagra online synthroid buy cheapest cialis zyrtec online how to clear acne preventive osteoporosis immune stimulants what is hoodia On Line Viagra getting over the pain diflucan dosage health asthma online stores hair loss products blood clot drugs colon parasites hair loss products discount medicine pravastatin buy griseofulvin tablets order indomethacin dog health products how to take a beta-blocker diazapan is valium treating cold sores chronic pain drug what is osteoporosis stress drug tooth whitening lowering cholesterol naturally legality of buying cialis online order levitra treatment for insomnia cheapest cialis index depakote overdose alprazolam condom sales treatment of yeast infection xanax sales taking viagra after cialis how to control pain new birth control chest pain health prozac prescription blood clots viagra in mexico chlamydia pill cancer drugs cold flu drugs how do i order viagra online super viagra acyclovir medicine benadryl dosage erythromycin pregnancy buy contoured condom chronic muscle pain pet health dogs treatment attention deficit disorder dental teeth whitening asthma medicine free prescription drugs herpes drug diabetes treatment buy tooth whitening gel cheap fast valium generic levitra buy cheapest viagra online lopressor drug pharmacy drug prices ultram dosing treatments for bipolar disorder neurontin withdrawal parasite medication chlamydia tips for increasing breast size ways to enhance breast what is valium used for metformin tablet order birth control hair loss for men how does xanax work treatment hepatitis c rythmol cheap acai antioxidants nexium generic blood pressure pills levitra online no prescription Levitra Online medications on line motion sickness drugs bactrim online order roxithromycin nicotine where can i order viagra immune supplements buy erexin v bph prostate allopurinol xanax for depression drug new smoking stop cheap impotence drug generic cialis delivery new treatment for depression antibiotics for cat viagra china alternative medicine cholesterol viagra dose anxiety disorder treatment severe muscle pain treatment of cancer calcium carbonate penis enlargement without pill valium maximum dosage reasons for high blood pressure energy product breast enlargement info cheap effexor building your body wrinkle cream aricept dosage alpha blocker increasing female sex drive valium depression new pain meds no rx xanax drug trileptal mg imitrex avapro 150mg medicine drugs contraception female claritin pill medication for acne med orders buy viagra internet levitra effect treatment for blood clots order sominex buy creatine buy precose cheap viagra overnight lopressor drug body building info health drugs general health and medical what is diazepam eye infections in dogs online prescription pills diclofenac tablet new medication anxiety buy citalopram medication male enhancement enhancement fat blocker medicine for throat infection order cardizem about soma health remedies for dogs generic xanax cheap zyrtec for depression medicine viagra sex domination buy acne skin care product hypnosis help study cure vaginal yeast infection weight loss supplement program muscle pain in leg how to increase erection buy viagra what is cla augmentin doses gaining muscle mass health med online heart rate treatments lopressor drug dog ear canal phentermine without prescription viagra order online weight loss glipizide diabetes astelin generic fat blocker buy gel tooth whitening cheap wellbutrin online weight loss program buy antiox anti-biotics acne skin treatmen tramadole vpxl pill drugs affecting levitra immune system support augmentin hypothyroidism medication buy erexin v uy prescription medication without a prescription buy discount order osteo arthritis online buy pilocarpine cheapest place to buy phentermine parasite treatment impotence help body fat loss viagra herb alternative constipation supplements treatment dementia adhd and medications muscle spasm relief viagra online cheap relieve upper back pain stop hair loss discount viagra online menstrual cycle problems antifungal shampoo side effects ativan gabapentin medication where can i buy viagra diazepam buy soma online clonidine dosage viagra gel top hair loss fast antibiotics cure chlamydia skin fungal infections drug zofran give up smoking alternative medicine cholesterol sleeping help best online viagra scams prednisone 10mg viagra sex domination lotensin easy weight loss pain meds without prescription over the counter drugs new high blood pressure medic generic compazine cetirizine drug order phentermine best fat blockers woman enhancement supplement drug zofran buy precose new drug treatment for cancer how to increase fertility viagra in australia benadryl dosing buy alcoholism medications order l arginine buy diazepam generic for ativan ativan prescription drugs weight loss treatment for chest pain woman health where can i buy phentermine online skin fungal infection give up smoking viagra on line hoodia information how does osteoporosis occur buy viagra online buy alcoholism medications depakote overdose klonopin pill tetracycline capsules what is high blood pressure bladder control for dogs generic for lipitor glucophage online pharmacy gabapentin dosage treating yeast infections dog health info cymbalta anxiety cheap tramadol without prescription hydrea drugs used for cancer cure for high blood pressure alcohol and valium relief from constipation liver infection treatment cialis soft zantac medication help sleep problems all natural antibiotics order medication without prescription sleep problems free hypnotherapy gaining muscle mass cheap viagra order online natural help for pain how to buy viagra drug price celebrex information otc diuretic levitra 10 mg buy medicine online pets products relief foot pain cialis without prescription med care cheapest generic cialis rapid hair loss pain medications generic side effects meds without prescriptions cat anxiety buy simplicef natural cure arthritis effects of high blood pressure lowest price generic viagra how to get birth control new breast cancer drug buy topamax blood pressure meds when are beta blockers prescribed how to get pain meds order fosamax online viagra name order viagra viagra cialis cat's eye health how to relieve lower back pain treating ear infections diazapan is valium online pain doctors high blood pressure in elderly medication to stop smoking wellbutrin dosages diabetes blood sugar levels weight loss diet pill side effects of prescribed pain pills drug list high blood pressure buy cialis online in usa ultram cost how to help osteoporosis how to use clomid discount brand viagra wellbutrin cymbalta buy pills without a prescription buy pain medicine online tab tramadol depression symptoms treatment how levitra work hypertension medications beta blockers prevent premature ejaculation xanax interactions with other medicines purchase medicine on line does alli work xenical mexico prescriptions buy sumycin uy prescription medication without a prescription ambien cost methocarbamol effects cheap beta blockers cats bladder reduce cholesterol naturally metformin tablet scabies medicine breast enhancer pills body building over 50 order viagra cheap zestril medication how to buy prescription medications online pharma kamagra drugs depression ear infection symptoms big muscle controlling blood pressure pain meds and pregnancy buy diazepam without prescription skin allergies antibiotic zoloft buy weight loss nutrition program Buy Cialis breast increase meds without prescriptions blood clots medical edema treatment for flu best hangover remedy diabetes drugs