Context
to facilitate
separation of concerns and achieve higher level of performance and
code predictability.See: Description
Class | Description |
---|---|
Allocator<T> |
This class represents an object allocator; instances of this class
are generated by
AllocatorContext . |
AllocatorContext |
This class represents an allocator context; it defines the
the allocation policy of the objects produced by
ObjectFactory . |
AllocatorContext.Reference<T> |
This class represents a
reference
allocated from the current AllocatorContext . |
ArrayFactory<T> |
This class holds factories to produces arrays of variable length.
|
ConcurrentContext |
This class represents a context to take advantage of concurrent
algorithms on multi-processors systems.
|
Context |
This class represents an execution context; they can be associated to
particular threads or objects.
|
HeapContext |
This class represents the default allocator context.
|
ImmortalContext |
This class represents an allocator from immortal memory (RTSJ).
|
LocalContext |
This class represents a context to define locally scoped environment
settings.
|
LocalContext.Reference<T> |
This class represents a reference whose setting is local to the current
LocalContext . |
LogContext |
This class represents a context for object-based/thread-based logging
capabilities.
|
ObjectFactory<T> |
This class represents an object factory; it allows for object
recycling, pre-allocation and stack allocations.
|
PersistentContext |
This class represents a context persistent accross multiple program
executions.
|
PersistentContext.Reference<T> |
This class represents a reference over an object which can be kept
persistent accross multiple program executions.
|
PoolContext |
This class represents a shared pool context for object
allocation/recycling.
|
SecurityContext |
This class represents a high-level security context (low level
security being addressed by the system security manager).
|
StackContext |
This class represents a stack
allocator context ;
(using thread-local pools or RTSJ ScopedMemory ). |
Exception | Description |
---|---|
ConcurrentException |
This class encapsulates errors or exceptions raised during the execution
of concurrent threads (
ConcurrentException are raised upon exit of
the ConcurrentContext ). |
Provides real-time Context
to facilitate
separation of concerns and achieve higher level of performance and
code predictability.
Separation of concerns is an important design principle greatly misunderstood. Most developers think it is limited to modularity and encapsulation or it requires special programming tools (e.g. Aspect programming).
Separation of concerns is very powerful and easier than it looks. Basically, it could be summarized as the "pass the buck principle". If you don't know what to do with some information, just give it to someone else who might know.
A frequent example is the catching of exceptions too early (with some logging processing) instead of throwing a checked exception. Unfortunately, they are still plenty of cases where the separation of concerns is not as good as it could be. For example logging! Why low-level code need to know which logging facility is being used (e.g. standard logging, Log4J library or anything else)? Furthermore, why logging should have to be based upon the class hierarchy (standard logging)?
Separation of concerns can be addressed through "Aspect Programming", but there is a rather simpler solution "Context Programming"!
It does not require any particular tool, it basically says that every threads
has a context which can be customized by someone else (the one who knows what to do).
Then, your code looks a lot cleaner and is way more flexible as you don't have
to worry about logging, security, performance etc. in your low level methods.
For example:
void myMethod() {
...
LogContext.info("Don't know where this is going to be logged to");
...
}
Used properly Javolution's contexts
greatly facilitate the separation of concerns. Contexts are
complemented by others classes such as for example the
Configurable
class to reduce
dependency between configuration and application code.
This package provides few predefined contexts:
LocalContext
- To define locally
scoped environment settings.ConcurrentContext
- To take advantage of concurrent
algorithms on multi-processors systems.AllocatorContext
- To control
object allocation, e.g. StackContext
to allocate on the stack (or RTSJ ScopedMemory).LogContext
- For thread-based or object-based logging
capability, e.g. StandardLog
to leverage standard
logging capabilities.
Note: java.util.logging
provides class-based
logging (based upon class hierarchy).PersistentContext
- To achieve persistency across
multiple program execution.SecurityContext
- To address application-level security
concerns.TestContext
- To address varied aspect of testing such as performance and regression. StackContext
?
You cannot get determinism using "any" library (including Java standard library)
regardless of the garbage collector issue. Array resizing, lazy initialization, map rehashing (...)
would all introduce unexpected delays (this is why Javolution comes with its own
real-time
collections implementation).
Still, you may use incremental/real-time collectors (if few milliseconds delays are acceptable).
These collectors work even faster if you limit the amount of garbage produced onto the heap
through stack allocations
.
It all depends upon the StackContext default
implementation.
The default implementation use thread-local queues (no synchronization required);
but if you run on a RTSJ virtual machine
entering a StackContext
could mean using ScopedMemory
.
Stack allocation is different from object pooling, it is a simple and transparent way to make your methods "clean" (no garbage generated), it has also the side effect of making your methods faster and more time-predictable. If all your methods are "clean" then your whole application is "clean", faster and more time-predictable (aka real-time).
In practice very few methods need to enter a StackContext
,
only the one generating a significant number of temporary objects (these methods are made "cleaner"
and faster through stack allocation). For example:
public final class DenseVector<F extends Field<F>> extends Vector<F> {
...
public F times(Vector<F> that) {
final int n = this.getDimension();
if (that.getDimension() != n) throw new DimensionException();
StackContext.enter();
try { // Reduces memory allocation / garbage collection.
F sum = this.get(0).times(that.get(0));
for (int i = 1; i < n; i++) {
sum = sum.plus(this.get(i).times(that.get(i)));
}
return StackContext.outerCopy(sum); // Stack object exported through copy.
} finally {
StackContext.exit(); // Resets stack.
}
}
...
}
Copyright © 2005 - 2009 Javolution.