KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javolution > context > Context


1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2006 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package javolution.context;
10
11 import j2me.io.Serializable;
12 import j2me.lang.IllegalStateException;
13 import j2me.lang.ThreadLocal;
14
15 /**
16  * <p> This class represents an execution context; they can be associated to
17  * particular threads or objects.</p>
18  *
19  * <p> This package provides few predefined contexts:<ul>
20  * <li>{@link LocalContext} - To define locally
21  * scoped setting held by {@link LocalContext.Reference}</li>
22  * <li>{@link PoolContext} - To transparently reuse objects created using
23  * an {@link ObjectFactory} instead of a constructor.</li>
24  * <li>{@link ConcurrentContext} - To take advantage of concurrent
25  * algorithms on multi-processors systems.</li>
26  * <li>{@link LogContext} - For thread-based or object-based logging
27  * capability.
28  * <i>Note: <code>java.util.logging</code> provides class-based
29  * logging (based upon class hierarchy).</i></li>
30  * <li>{@link PersistentContext} - To achieve persistency accross
31  * multiple program execution.</li>
32  * </ul>
33  * Context-aware applications may extend the context base class or any
34  * predefined contexts in order to facilitate separation of concern
35  * (e.g. logging, security, performance and so forth).</p>
36  *
37  * <p> The scope of a {@link Context} should be surrounded by a <code>try,
38  * finally</code> block statement to ensure correct behavior in case
39  * of exceptions being raised. For example:[code]
40  * LocalContext.enter(); // Current thread enter a local context.
41  * try
42  * ModuloInteger.setModulus(m); // No impact on other threads!
43  * z = x.times(y); // Multiplication modulo m.
44  * } finally {
45  * LocalContext.exit();
46  * }
47  *
48  * public class Calculator { // Sandbox calculator which does not generate garbage!
49  * private static final PoolContext _pool = new PoolContext(); // Pool for temporary objects.
50  * public Complex multiply(Vector<Complex> left, Vector<Complex> right) {
51  * PoolContext.enter(_pool); // Ensures that the current thread uses the calculator pool.
52  * try {
53  * return left.times(right).export(); // Result is exported (out of the pool).
54  * } finally {
55  * PoolContext.exit(_pool); // Recycles all temporary objects (stack reset).
56  * }
57  * }
58  * }[/code]</p>
59  *
60  * <p> Finally, context instances can be serialized/deserialized in
61  * {@link javolution.xml.XMLFormat XMLFormat}. For example,
62  * applications may want to load pool contexts at start-up to limit
63  * the number of object creation at run-time (and therefore reduce
64  * the worst-case execution time).</p>
65  *
66  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
67  * @version 4.2, December 14, 2006
68  */

69 public abstract class Context extends RealtimeObject implements Serializable {
70
71     /**
72      * Holds the root context (top context of all threads).
73      */

74     public static final HeapContext ROOT = new HeapContext();
75     
76     /**
77      * Holds the current context (thread-local).
78      */

79     private static final ThreadLocal JavaDoc CURRENT = new ThreadLocal JavaDoc() {
80         protected Object JavaDoc initialValue() {
81             return ROOT;
82         }
83     };
84    
85     /**
86      * Holds the current owner of this context or <code>null</code>.
87      */

88     transient Thread JavaDoc _owner;
89
90     /**
91      * Holds the outer context or <code>null</code> if none (root context).
92      */

93     transient Context _outer;
94
95     /**
96      * Default constructor.
97      */

98     protected Context() {
99     }
100
101     /**
102      * Returns the current context for the current thread. The default context
103      * for a new thread is a {@link #ROOT}. {@link ConcurrentExecutor}
104      * have the same context as the calling thread.
105      *
106      * @return the current context.
107      */

108     public static Context current() {
109         return (Context) Context.CURRENT.get();
110     }
111
112     /**
113      * Returns the current owner of this context. The owner of a
114      * context is the thread which {@link #enter(Context) entered}
115      * the context and has not yet {@link #exit(Context) exited}.
116      * A context can only have one owner at any given time, although
117      * contexts can be shared by multiple {@link ConcurrentExecutor}).
118      *
119      * @return the thread owner of this context or <code>null</code>.
120      */

121     public final Thread JavaDoc getOwner() {
122         return _owner;
123     }
124
125     /**
126      * Holds the outer context of this context or <code>null</code>
127      * if {@link #ROOT}.
128      *
129      * @return the outer context or <code>null</code>.
130      */

131     public final Context getOuter() {
132         return _outer;
133     }
134
135     /**
136      * The action to be performed after this context becomes the current
137      * context.
138      */

139     protected abstract void enterAction();
140
141     /**
142      * The action to be performed before this context is no more the current
143      * context.
144      */

145     protected abstract void exitAction();
146
147     /**
148      * Enters the specified context.
149      *
150      * @param context the context being entered.
151      * @throws IllegalStateException if this context is currently in use.
152      */

153     public static void enter(Context context) {
154         if (context._owner != null)
155             throw new IllegalStateException JavaDoc("Context is currently in use");
156         Context current = Context.current();
157         context._outer = current;
158         context._owner = Thread.currentThread();
159         Context.CURRENT.set(context);
160         context.enterAction();
161     }
162
163     /**
164      * Exits the specified context. The {@link #getOuter outer} context
165      * becomes the current context.
166      *
167      * @param context the context being entered.
168      * @throws IllegalArgumentException if the specified context is not the current context.
169      * @throws IllegalStateException if this context is not the current context
170      * or does not belong to the current thread.
171      */

172     public static void exit(Context context) {
173         if (context != Context.current())
174             throw new IllegalStateException JavaDoc("The Specified context is not the current context");
175        if (context._owner != Thread.currentThread()) // Only possible for ConcurrentContext.
176
throw new IllegalStateException JavaDoc("Cannot exit context belonging to another thread");
177        exitNoCheck(context);
178     }
179     static void exitNoCheck(Context context) {
180         try {
181             context.exitAction();
182         } finally {
183             Context.CURRENT.set(context._outer);
184             context._outer = null;
185             context._owner = null;
186         }
187     }
188
189     /**
190      * Sets the current context, used by {@link ConcurrentContext}
191      * exclusively.
192      */

193     static void setCurrent(ConcurrentContext context) {
194         Context.CURRENT.set(context);
195     }
196     
197     /**
198      * Sets the pools of this context active or inactive.
199      * This method is overriden by HeapContext and PoolContext.
200      *
201      * @param value indicates if pools should be activated or desactivated.
202      */

203     void setPoolsActive(boolean value) {
204         _outer.setPoolsActive(value);
205     }
206
207     /**
208      * Returns the local pools for the current thread and for this context.
209      *
210      * @return the thread local pools for this context.
211      */

212     LocalPools getLocalPools() {
213         return _outer.getLocalPools();
214     }
215
216 }
Popular Tags