Skip to main content

Anomalies with Double check locking

Already we have a nice article about about problems with double check locking. we will see two nice quick workarounds  and its pros and cons.Double-checked locking: Clever, but broken and Double-Checked Locking is Broken.

before getting into solution, classic singleton uses the following signature for get instance:
     public static  Resource getResource() {
    if (resource == null)
      resource = new Resource();
    return resource;
  }
so the above code will only create the new resource object if  no instance of resource is found. This mechanism is  called lazy loading more preciously need based loading we only load resources if and only if it is required. Benefit associated with this approach is performance  improvement, if resource creation is a heavy process and we do not want it to be carried when class is loading t  then this classic approach does make sense.

public static synchronized Resource getResource() {
    if (resource == null)
      resource = new Resource();
    return resource;
  }
 
 we just make that getInstance method synchronized and rest remain same as classic singleton,  so object is created only if it is required. How ever there is a downside to it, synchronization is expensive, it takes more time to run method with  synchronized keyword than ordinary method. Since getInstance is synchronized every call to this method will be more expensive.

Another work around is to use a static initializer to create singleton object as soon as class is loaded by class loader;

class Singleton{
private static Singletonr  singleton=new Singleton();

public static   Singleton getInstance(){
         return  singleton;
       
    }
}

This is guaranteed to be thread safe. The downside of creating singleton like this we are creating it eagerly so singleton is always created even if it is never needed.

So both the approach has its strengths  and downsides associated with it, we can select our approach based on application's need .

an example  with second approach:


class ReduceNto1{

    int max=0;
    private static ReduceNto1 r1=new ReduceNto1();
   
    public static   ReduceNto1 getInstance(){
            return r1;
         }
   
    private ReduceNto1(){}
   
   
    public synchronized  void  setMax(int n){
   
       
        System.out.println("***"+n);
           
            if(n>max){
                max=n;
            }
           
       
    }   
       
   
   
    public int getMax(){
        return max;
    }

   
   
}

class MaxFinder implements  Runnable {

    int max=Integer.MIN_VALUE;
    int arr[];
   
    public MaxFinder(int arr[]){
        this.arr=arr;
    }
    public void run() {
      findMax();   
      System.out.println(max);
      System.out.println(Thread.currentThread().getName()+"****setting max from this thread to reduce*****"+max);
      ReduceNto1.getInstance().setMax(max);
     
    }


    public void findMax(){
       
       
        for(int i=0;i<arr.length;i++){
       
            if(arr[i]>max)
                max=arr[i];
        }
   
       
    }
   
    public int getMax(){
        return max;
    }
}



public class ConcurrentReadingFromNarray {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
       
        int arr1[]={1,2,3,4,5,49,7,49,9,10};
        int arr2[]={11,12,13,14,15,16,17,18,19,20};
        Thread t1=new Thread(new MaxFinder(arr1));
        Thread t2=new Thread(new MaxFinder(arr2));
        t1.start();
        t2.start();
        try{
            t1.join();
            t2.join();
        }catch(Exception e){}
        System.out.println("Max No is : "+ReduceNto1.getInstance().getMax());

    }

}
Out Put:

20
49
Thread-0****setting max from this thread to reduce*****49
Thread-1****setting max from this thread to reduce*****20
***20
***49
Max No is : 49


Note:

I am  prone to  typo; please report them and I will try to update the posts accordingly.

    
 

Comments

Popular posts from this blog

Greedy algorithms for Job Scheduling

In this programming problem and the next you'll code up the greedy algorithms from lecture for minimizing the weighted sum of completion times.. This file describes a set of jobs with positive and integral weights and lengths. It has the format [number_of_jobs] [job_1_weight] [job_1_length] [job_2_weight] [job_2_length] ... For example, the third line of the file is "74 59", indicating that the second job has weight 74 and length 59. You should NOT assume that edge weights or lengths are distinct. Your task in this problem is to run the greedy algorithm that schedules jobs in decreasing order of the difference (weight - length). This algorithm is not always optimal. IMPORTANT: if two jobs have equal difference (weight - length), you should schedule the job with higher weight first. Beware: if you break ties in a different way, you are likely to get the wrong answer. You should report the sum of weighted completion times of the resulting schedule --- a posi
You are given four integers 'a', 'b', 'y' and 'x', where 'x' can only be either zero or one. Your task is as follows: If 'x' is zero assign value 'a' to the variable 'y', if 'x' is one assign value 'b' to the variable 'y'. You are not allowed to use any conditional operator (including ternary operator).  Possible Solutions: 1. y = (1 - x) * a + x * b; 2.y = a ^ ((a ^ b) & (x))