Saturday, 2 April 2016

Static member class vs. nonstatic

Wherever you use a static member class, you can always remove the static keyword, and it still works. But it will have an unnecessary reference to the enclosing instance (the Outer class's instance)

If we add static on Inner class, it won't compile. Because static member class doesn't know about Outer class's instance.

 public class Outer {  
   public void doit(){  
     Inner inner = new Inner();  
     inner.doit();  
   }  
   private void doitAgain(){  
     System.out.println("do it again");  
   }  
   private class Inner {  
     public void doit() {  
       Outer.this.doitAgain();  
     }  
   }  
   public static void main(String[] args){  
     new Outer().doit();  
   }  
 }  

Friday, 1 April 2016

Callback

Suppose you want to check the progress of some work. You can choose to query the status from the server regularly. But this solution sucks right? It's like asking taxi driver every 5 minutes how far away the destination is.

 class Server{  
   private int progress;  
   public int getProgress(){ return progress;  }  
   public void copy() {  
     while(progress <100){  
       try{  
         Thread.sleep(10);  
         progress++;  
       }catch(InterruptedException e){}  
     }  
   }  
 }  
 public class NoCallbackClient {  
   private Server server = new Server();  
   public void call() {  
     server.copy();  
   }  
   public static void main(String[] args) throws InterruptedException{  
     final NoCallbackClient client = new NoCallbackClient();  
     Runnable r = ()->client.call();  
     new Thread(r).start();  
     System.out.print("Progress: ");  
     while(true){  
       int progress = client.server.getProgress();  
       Thread.sleep(200);  
       if(progress >= 100){  
         break;  
       }else{  
         System.out.print(progress+"% ");  
       }  
     }  
   }  
 }  

So instead of keeping asking the taxi driver, you should say to the driver, "Hey, let me know when we are 25%, 50%, 75% into our journey".

Here is what callback does.

 package callback;  
 interface IClient{  
   void callback(int i);  
 }  
 class Server{  
   private IClient client;  
   public Server(IClient client) {  
     this.client = client;  
   }  
   public void copy() {  
     for(int i=0;i<=100;i++){  
       if (i%10 == 0) {  
         client.callback(i);  
       }  
     }  
   }  
 }  
 public class CallbackClient implements IClient{  
   public void call() {  
     new Server(this).copy();  
   }  
   @Override public void callback(int i) {  
     System.out.print(i+"% ");  
   }  
   public static void main(String[] args){  
     new CallbackClient().call();  
   }  
 }  

Reference: http://blog.csdn.net/yqj2065/article/details/39481255

Wednesday, 30 March 2016

Volatile and double-checked locking

https://en.wikipedia.org/wiki/Singleton_pattern#Java_5_solution

This is a lazy initialization of singleton.

What does volatile do here?

1:  public final class SingletonDemo {  
2:    private static volatile SingletonDemo instance;  
3:    private SingletonDemo() { }  
4:    public static SingletonDemo getInstance() {  
5:      if (instance == null ) {  
6:        synchronized (SingletonDemo.class) {  
7:          if (instance == null) {  
8:            instance = new SingletonDemo();  
9:          }  
10:        }  
11:      }  
12:      return instance;  
13:    }  
14:  }  
Well, volatile ensures one thread can always read the up-to-date value of the variable updated by another thread.

What happens if we remove volatile?

OK, brain exercise time. Suppose two threads A and B come to this getInstance() method.

At time 100: Both A and B arrive at line 5
At time 101: A enters the synchronized block, B waits outside
At time 105: A exits the synchronized block at line 12
At time 106: B enters the synchronized block at line 7

Question: For thread B, is 'instance' equal to null now? Not necessarily without the volatile keyword. It might still seem to be null to B although it has in fact been assigned some value.

Next question: is there any advantage of using double-checked lock over the following implementation, which looks much neater.
1:  public final class SingletonDemo {  
2:    private static SingletonDemo instance = null;  
3:    private SingletonDemo() { }  
4:    public static synchronized SingletonDemo getInstance() {  
5:      if (instance == null) {  
6:        instance = new SingletonDemo();  
7:      }  
8:      return instance;  
9:    }  
10:  }  

I guess when the number of threads is high, the 2nd implementation is slower because of the synchronized keyword on the method. For the 1st implementation, once the object has been created, the synchronized block won't be executed at all.

Tuesday, 29 March 2016

Builder pattern

Quick template code

 public class FullName {  
   private final String firstName;  
   private final String lastName;  
   public static class Builder{  
     private String firstName;  
     private String lastName;  
     public Builder(){}  
     public Builder firstName(String firstName){  
       this.firstName = firstName;  
       return this;  
     }  
     public Builder lastName(String lastName){  
       this.lastName = lastName;  
       return this;  
     }  
     public FullName build(){  
       return new FullName(this);  
     }  
   }  
   private FullName(Builder builder) {  
     firstName = builder.firstName;  
     lastName = builder.lastName;  
   }  
 }  

Client code

 FullName name = new FullName.Builder().firstName("Ming").lastName("Sun").build();  

Finalizer guardian

"Effective Java" Item 7: Avoid finalizer

In the last few paragraphs, a concept of 'Finalizer guardian' is introduced. It took me a while to get my head around it. So I would like to share my understanding.

When we override a class's finalize() method, it is important we call super.finalize(), because its super class may want to close some critical resources. However, people don't always remember to call super.finalize(). Here the finalizer guadian comes to rescue.

Let's have a look at an example. OK, here we forget to call super.finalize()

 public class FooSub extends Foo {  
   @Override  
   protected void finalize() throws Throwable {  
     System.out.println("FooSub garbage collected");  
   }  
 }  

But with finalizer Guardian, everything is still under control.

 public class Foo {  
   private CriticalResource criticalResource = new CriticalResource();  
   private final Object finalizerGuardian = new Object(){  
     @Override  
     protected void finalize() throws Throwable {  
       System.out.println("Critical resource closed");  
       criticalResource.close();  
     }  
   };  
   private static class CriticalResource implements Closeable{  
     public void close() throws IOException {  
     }  
   }  
 }  


 public static void main(String[] args) {  
     FooSub foo = new FooSub();  
     foo = null;  
     System.gc();  
   }  

Check the output

 Critical resource closed
 FooSub garbage collected 

Sunday, 27 March 2016

jQuery Ready handler

<html>
  <head>
    <title>JQuery</title>
 <script src="script/jquery-1.12.2.js" type="text/javascript"></script>
 <script type="text/javascript">
   var $ = 'Hi!';
       jQuery(function(){
     alert('$ = ' + $);
   });     
 </script>
  </head>
  <body>Hi</body>
</html>
Since $ variable gets overridden here, the result is '$ = Hi!'

Now add a $ as a parameter

 <script type="text/javascript">
   var $ = 'Hi!';
       jQuery(function($){
     alert('$ = ' + $);
   });     
 </script>

The result is '$ is function (select, context)......'

Because $ is a local variable now. The global variable $ = 'Hi!' takes no effect.

Weak reference

What is weak reference?

To understand weak reference, first look at strong reference.

String s = new String("hello world");

This is strong reference. Only when s becomes null will the object 'new String("hello world")' become eligible for garbage collection.

 
Map strongMap = new HashMap();
Cat key = new Cat();
Object value = new Object();
strongMap.put(key, value);
key = null;
value = null;

The key in the map is also strong reference. Even though the key variable is set to null, the 'new Cat()' object cannot be garbage collected.
 
Map weakMap = new WeakHashMap();
Cat key = new Cat();
Object value = new Object();
weakMap.put(key, value);
key = null;
value = null;

Now that we put the key/value pair into a WeakHashMap, the 'new Cat()' object does become garbage collected once the key is set to null.

Here is a complete program to illustrate the difference.

First a utility class
 
private static class MyKey {
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("Gabage collected");
    }
}

StrongMap
public static void main(String[] args) {
    Map<MyKey, Object> strongMap = new HashMap<MyKey, Object>();
    for (int i = 0; i < 1000; i++){
       for (int j=0; j < 10000; j++){
            MyKey key = new MyKey();
            Object value = new Object();
            strongMap.put(key, value);
        }
    }
}
Output is OutOfMemory error

WeakMap
public static void main(String[] args) {
    Map<MyKey, Object> weakMap = new WeakHashMap<MyKey, Object>();
    for (int i = 0; i < 1000; i++){
       for (int j=0; j < 10000; j++){
            MyKey key = new MyKey();
            Object value = new Object();
            weakMap.put(key, value);
        }
    }
}

Output is tons of "Gabage collected" message and you don't see an OutOfMemory error.