cz.cuni.amis.utils.flag
Class ImmutableFlag<T>

java.lang.Object
  extended by cz.cuni.amis.utils.flag.Flag<T>
      extended by cz.cuni.amis.utils.flag.ImmutableFlag<T>
All Implemented Interfaces:
IFlag<T>, java.io.Serializable
Direct Known Subclasses:
ImmutableReasonFlag

public class ImmutableFlag<T>
extends Flag<T>
implements java.io.Serializable

Flag whhich value cannot be set.

See Also:
Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from class cz.cuni.amis.utils.flag.Flag
Flag.DoInSync<T>
 
Field Summary
protected  IFlag<T> flag
           
 
Constructor Summary
ImmutableFlag(IFlag<T> flag)
          Creates a new instance of ImmutableFlag
 
Method Summary
 void addListener(FlagListener<T> listener)
          Adds new listener to the flag with specified param.
 void addStrongListener(FlagListener<T> listener)
          Adds new listener to the flag (strong reference).
 void clearListeners()
          Call to clear (remove) all the listeners on the flag.
 void defreeze()
          Method is synchronized.
 void freeze()
          This method will freeze the processing of the setFlag() method.
 T getFlag()
          Returns the value of the flag.
 ImmutableFlag<T> getImmutable()
           
 void inSync(Flag.DoInSync<T> command)
          Add a command (to the end of the queue) that will be executed in-sync with other changes (you may be sure that no other changes are taking place right now).
 boolean isFrozen()
          Whether the flag-change has been frozen, i.e., setFlag() won't change the flag value immediately by will wait till Flag.defreeze() is called.
 boolean isListenning(FlagListener<T> listener)
          Checks whether listener is already registered (using equals()).
 void removeListener(FlagListener<T> listener)
          Removes all registered 'listener' from the flag.
 void setFlag(T newValue)
          Changes the flag and informs all listeners.
 
Methods inherited from class cz.cuni.amis.utils.flag.Flag
inSyncInner, isNone, isOne, removeAllListeners, waitFor, waitFor, waitForChange, waitForChange
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

flag

protected IFlag<T> flag
Constructor Detail

ImmutableFlag

public ImmutableFlag(IFlag<T> flag)
Creates a new instance of ImmutableFlag

Method Detail

addListener

public void addListener(FlagListener<T> listener)
Description copied from class: Flag
Adds new listener to the flag with specified param. It will weak-reference the listener so when you drop the references to it, it will be automatically garbage-collected.

Note that all anonymous listeners are not subject to gc() because they are reachable from within the object where they were created.

Specified by:
addListener in interface IFlag<T>
Overrides:
addListener in class Flag<T>

addStrongListener

public void addStrongListener(FlagListener<T> listener)
Description copied from class: Flag
Adds new listener to the flag (strong reference).

Using this method is memory-leak prone.

Specified by:
addStrongListener in interface IFlag<T>
Overrides:
addStrongListener in class Flag<T>

clearListeners

public void clearListeners()
Description copied from class: Flag
Call to clear (remove) all the listeners on the flag.

Should be used when the flag isn't going to be used again to allow GC to collect the listeners (for instance anonymous objects).

Specified by:
clearListeners in interface IFlag<T>
Overrides:
clearListeners in class Flag<T>

getFlag

public T getFlag()
Description copied from class: Flag
Returns the value of the flag.

Note that if the flag contains any set-flag pending requests queue it will return the last value from this queue.

This has a big advantage for the multi-thread heavy-listener oriented designs.

Every time a listener is informed about the flag change it receives a new value of the flag but additionally it may query the flag for the last value there will be set into it.

Note that if you use the Flag sparingly this mechanism won't affect you in 99.99999% of time.

Warning - this method won't return truly a correct value if you will use inSync() method because this time we won't be able to obtain the concrete value of the flag after the DoInSync command will be carried out - instead we return the first value we are aware of. Again this won't affect you in any way (... but you should know such behavior exist ;-))

Specified by:
getFlag in interface IFlag<T>
Overrides:
getFlag in class Flag<T>
Returns:
value of the flag

isListenning

public boolean isListenning(FlagListener<T> listener)
Description copied from class: Flag
Checks whether listener is already registered (using equals()).

Specified by:
isListenning in interface IFlag<T>
Overrides:
isListenning in class Flag<T>
Returns:
true if listener is already registered

removeListener

public void removeListener(FlagListener<T> listener)
Description copied from class: Flag
Removes all registered 'listener' from the flag.

Specified by:
removeListener in interface IFlag<T>
Overrides:
removeListener in class Flag<T>

setFlag

public void setFlag(T newValue)
Description copied from class: Flag
Changes the flag and informs all listeners.

Specified by:
setFlag in interface IFlag<T>
Overrides:
setFlag in class Flag<T>

getImmutable

public ImmutableFlag<T> getImmutable()
Specified by:
getImmutable in interface IFlag<T>
Overrides:
getImmutable in class Flag<T>
Returns:
Immutable version of this flag, setFlag(T) method of such a flag will raise an exception.

inSync

public void inSync(Flag.DoInSync<T> command)
Description copied from class: Flag
Add a command (to the end of the queue) that will be executed in-sync with other changes (you may be sure that no other changes are taking place right now).

This is also used by the setFlag() method.

Specified by:
inSync in interface IFlag<T>
Overrides:
inSync in class Flag<T>

isFrozen

public boolean isFrozen()
Description copied from class: Flag
Whether the flag-change has been frozen, i.e., setFlag() won't change the flag value immediately by will wait till Flag.defreeze() is called.

Specified by:
isFrozen in interface IFlag<T>
Overrides:
isFrozen in class Flag<T>

freeze

public void freeze()
Description copied from class: Flag
This method will freeze the processing of the setFlag() method. Method is synchronized.

It waits until all setFlag() pending requests are resolved and then returns.

It may be used to for the synchronized registration of the listeners (if you really care for the value of the flag before creating the listener). Or it may be used to obtain a true value of the flag in the moment of the method call (as it waits for all the listeners to execute).

In one of these cases, do this:

  1. flag.freeze()
  2. examine the flag value and/or register new listeners
  3. flag.defreeze() // DO NOT FORGET THIS!

Example: you have a flag that is counting how many alive threads you have, those threads may be created concurrently ... without this synchronizing method you wouldn't be able to correctly read the number of threads before incrementing the flag.

Beware of deadlocks when using this method, watch out:

a) infinite recursion during the setFlag() (listeners are changing the flag value repeatedly)

b) incorrect sequences of the freeze() / defreeze() calls

Of course you may simulate this behavior with simple synchronized() statement, but this isn't always feasible as it blocks all other threads while accessing this flag, note that this flag implementation promotes non-blocking methods.

Specified by:
freeze in interface IFlag<T>
Overrides:
freeze in class Flag<T>

defreeze

public void defreeze()
Description copied from class: Flag
Method is synchronized. See Flag.freeze() for info.

Specified by:
defreeze in interface IFlag<T>
Overrides:
defreeze in class Flag<T>