Monday, December 31, 2012

Java WeakReference, SoftReference and WeakHashMap

Strong reference

A strong reference is an ordinary Java reference. Usually Java references will be implemented as pointers, but that's not required by the language specification. They may be using an additional layer of indirection to enable easier garbage collection. References interacts with garbage collector.  Specifically, if an object is reachable via a chain of strong references (strongly reachable), it is not eligible for garbage collection. This is normally exactly what you want.

Weak reference

One problem with strong references is caching, particular with very large structures like images, sounds, etc. Cache is common source of memory leaks. Once you put an object reference into a cache, it’s easy to forget that it’s there and leave it in the cache long after it becomes irrelevant. 

To solve this problem you need to implement a cache for which an entry is relevant exactlyso long as there are references to its key outside of the cache.

Weak reference leverage the garbage collector's ability to determine reachability for you.

You can create and use Weak reference like this (for some imaginary Car object and car object instance):

//Create weak car reference.
WeakReference<Car> weakCar = new WeakReference<Car>(car);
//Then to get actual car instance use following:
Car weakCarRef = weakCar.get();
 Weak reference isn't strong enough to prevent garbage collection, so you may find that .get() suddenly starts returning null. Which is basically what you want in the first place, but usually WeakReferences are used together with WeakHashMap class.

In WeakHashMap entries will be removed automatically after they become obsolete. Remember that WeakHashMap is useful only if the desired lifetime of cache entries is determined by external references to the key, not the value.

Using WeakHashMap is simple because it uses same Map interface that is used for HashMap and all basic Map data structures in Java.

Soft reference

soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers. In practice softly reachable objects are generally retained as long as memory is in plentiful supply.

Use it or not to use it?
Personally I don't like weak, soft and phantom references because you basically hand control of you program to GC and he will decide when is the time to remove reference, not you. 

Sunday, December 30, 2012

Desing Patterns in Java - Command pattern

Description

Command pattern is an object behavioral pattern that allows us to achieve complete decoupling between the sender and the receiver. (A sender is an object that invokes an operation, and a receiver is an object that receives the request to execute a certain operation.

This pattern allows the requester of a particular action to be decoupled from the object that performs the action.

This pattern encodes the details needed to send a message to an object. Such messages can be invoked along different points of time or location in a general way without having to hard-code its details. It allows messages to be invoked one or more times, or passed along to different parts of the system or multiple systems without requiring the details of a specific invocation to be known before execution.

Object references VS function pointers

Some languages (C for example) support function pointers facilities that allow programs to store and transmit the ability to invoke a particular function. Java does not provide function pointers, but object references together with dynamic loading and binding mechanism can be used to achieve a similar effect. This is where command pattern comes into play.

Example

We will use simple remote control for CD Player as example. This simple CD Player support only basic commands (Play, Stop and Pause), but that is good enough for out example of command pattern.

//Cd Player that will be controlled by remote control
public class CdPlayer {

  public enum State {
    PAUSE, PLAY, STOP
  }

  private State state;

  public void pause() {
    state = State.PAUSE;
  }

  public void stop() {
    state = State.STOP;
  }

  public void play() {
    state = State.PLAY;
  }

  public State getState() {
    return state;
  }

}
//Simple command interface.
public interface Command { 
  void execute(); 
}
//Cd Player remote control that will control Cd Player through button press.
public class CdPlayerRemoteControl {
 
  private Command command;
 
  public void setCommand(Command command) {
    this.command = command;
  } 
 
  public void pressButton() {
    command.execute();
  }
}

//Cd Player play command.
public class CdPlayerPlayCommand implements Command {

  private CdPlayer cdPlayer;
 
  public CdPlayerPlayCommand(CdPlayer cdPlayer) {
    this.cdPlayer = cdPlayer;
  }
 
  public void execute() {
    cdPlayer.play();
  }
 
}
//Cd Player pause command.
public class CdPlayerPauseCommand implements Command {

  private CdPlayer cdPlayer;
 
  public CdPlayerPauseCommand(CdPlayer cdPlayer) {
    this.cdPlayer = cdPlayer;
  }
 
  public void execute() {
    cdPlayer.pause();
  }
 
}
//Stop command...
public class CdPlayerStopCommand implements Command {
 
  private CdPlayer cdPlayer;
 
  public CdPlayerStopCommand(CdPlayer cdPlayer) {
    this.cdPlayer = cdPlayer;
  }
 
  public void execute() {
    cdPlayer.stop();
  }
 
}
//Client class that uses remote control for CD Player control.
public class Client {
 
  public static void main(String[] args) {
    CdPlayerRemoteControl cdPlayerRemoteControl = new CdPlayerRemoteControl();  
    CdPlayer cdPlayer = new CdPlayer();
    
    Command play = new CdPlayerPlayCommand(cdPlayer);
    Command pause = new CdPlayerPauseCommand(cdPlayer);
    Command stop = new CdPlayerStopCommand(cdPlayer);
  
    //Play music  
    cdPlayerRemoteControl.setCommand(play);
    cdPlayerRemoteControl.pressButton();
    
    //Stop music
    cdPlayerRemoteControl.setCommand(stop);
    cdPlayerRemoteControl.pressButton();
  
    //prints STOP
    System.out.println(cdPlayer.getState());
  
  }
 
}