Class Realm

  • Direct Known Subclasses:
    DisplayRealm

    public abstract class Realm
    extends Object
    A realm defines a context from which objects implementing IObservable must be accessed, and on which these objects will notify their listeners. To bridge between observables from different realms, subclasses of Binding can be used.

    A block of code is said to be executing within a realm if calling isCurrent() from that block returns true. Code reached by calling methods from that block will execute within the same realm, with the exception of methods on this class that can be used to execute code within a specific realm. Clients can use syncExec(Runnable), asyncExec(Runnable), or exec(Runnable) to execute a runnable within this realm. Note that using syncExec(Runnable) can lead to deadlocks and should be avoided if the current thread holds any locks.

    It is instructive to think about possible implementations of Realm: It can be based on executing on a designated thread such as a UI thread, or based on holding a lock. In the former case, calling syncExec on a realm that is not the current realm will execute the given runnable on a different thread (the designated thread). In the latter case, calling syncExec may execute the given runnable on the calling thread, but calling asyncExec(Runnable) will execute the given runnable on a different thread. Therefore, no assumptions can be made about the thread that will execute arguments to asyncExec(Runnable), syncExec(Runnable), or exec(Runnable).

    It is possible that a block of code is executing within more than one realm. This can happen for implementations of Realm that are based on holding a lock but don't use a separate thread to run runnables given to syncExec(Runnable). Realm implementations of this kind should be appropriately documented because it increases the opportunity for deadlock.

    Some implementations of IObservable provide constructors which do not take a Realm argument and are specified to create the observable instance with the current default realm. The default realm can be set for the currently executing thread by using runWithDefault(Realm, Runnable). Note that the default realm does not have to be the current realm.

    Subclasses must override at least one of asyncExec()/syncExec(). For realms based on a designated thread, it may be easier to implement asyncExec and keep the default implementation of syncExec. For realms based on holding a lock, it may be easier to implement syncExec and keep the default implementation of asyncExec.

    Since:
    1.0
    See Also:
    IObservable
    • Constructor Detail

      • Realm

        public Realm()
    • Method Detail

      • getDefault

        public static Realm getDefault()
        Returns the default realm for the calling thread, or null if no default realm has been set.
        Returns:
        the default realm, or null
      • setDefault

        protected static Realm setDefault​(Realm realm)
        Sets the default realm for the calling thread, returning the current default thread. This method is inherently unsafe, it is recommended to use runWithDefault(Realm, Runnable) instead. This method is exposed to subclasses to facilitate testing.
        Parameters:
        realm - the new default realm, or null
        Returns:
        the previous default realm, or null
      • isCurrent

        public abstract boolean isCurrent()
        Returns:
        true if the caller is executing in this realm. This method must not have side-effects (such as, for example, implicitly placing the caller in this realm).
      • safeRun

        protected static void safeRun​(Runnable runnable)
        Runs the given runnable. If an exception occurs within the runnable, it is logged and not re-thrown. If the runnable implements ISafeRunnable, the exception is passed to its handleException method.
        Parameters:
        runnable -
      • exec

        public void exec​(Runnable runnable)
        Causes the run() method of the runnable to be invoked from within this realm. If the caller is executing in this realm, the runnable's run method is invoked directly, otherwise it is run at the next reasonable opportunity using asyncExec.

        If the given runnable is an instance of ISafeRunnable, its exception handler method will be called if any exceptions occur while running it. Otherwise, the exception will be logged.

        Parameters:
        runnable -
      • asyncExec

        public void asyncExec​(Runnable runnable)
        Causes the run() method of the runnable to be invoked from within this realm at the next reasonable opportunity. The caller of this method continues to run in parallel, and is not notified when the runnable has completed.

        If the given runnable is an instance of ISafeRunnable, its exception handler method will be called if any exceptions occur while running it. Otherwise, the exception will be logged.

        Subclasses should use safeRun(Runnable) to run the runnable.

        Parameters:
        runnable -
      • timerExec

        public void timerExec​(int milliseconds,
                              Runnable runnable)
        Causes the run() method of the runnable to be invoked from within this realm after the specified number of milliseconds have elapsed. If milliseconds is less than zero, the runnable is not executed. The caller of this method continues to run in parallel, and is not notified when the runnable has completed.

        If the given runnable is an instance of ISafeRunnable, its exception handler method will be called if any exceptions occur while running it. Otherwise, the exception will be logged.

        Subclasses should use safeRun(Runnable) to run the runnable.

        Parameters:
        milliseconds -
        runnable -
        Since:
        1.2
      • syncExec

        protected void syncExec​(Runnable runnable)
        Causes the run() method of the runnable to be invoked from within this realm at the next reasonable opportunity. This method is blocking the caller until the runnable completes.

        If the given runnable is an instance of ISafeRunnable, its exception handler method will be called if any exceptions occur while running it. Otherwise, the exception will be logged.

        Subclasses should use safeRun(Runnable) to run the runnable.

        Note: This class is not meant to be called by clients and therefore has only protected access.

        Parameters:
        runnable -
      • runWithDefault

        public static void runWithDefault​(Realm realm,
                                          Runnable runnable)
        Sets the provided realm as the default for the duration of Runnable.run() and resets the previous realm after completion. Note that this will not set the given realm as the current realm.
        Parameters:
        realm -
        runnable -