|
J avolution v5.2 (J2SE 1.5+) | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectjavolution.context.Context
javolution.context.ConcurrentContext
public abstract class ConcurrentContext
This class represents a context to take advantage of concurrent algorithms on multi-processors systems.
When a thread enters a concurrent context, it may performs concurrent
executions by calling the execute(Runnable)
static method.
The logic is then executed by a concurrent thread or by the current
thread itself if there is no concurrent thread immediately available
(the number of concurrent threads is limited, see
Javolution Configuration for details).
Only after all concurrent executions are completed, is the current thread allowed to exit the scope of the concurrent context (internal synchronization).
Concurrent logics always execute within the same Context
as
the calling thread. For example, if the main thread runs in a
StackContext
, concurrent executions are performed in the
same StackContext
as well.
Concurrent contexts are easy to use, and provide automatic
load-balancing between processors with almost no overhead. Here is
an example of concurrent/recursive implementation of the
Karatsuba multiplication for large integers:
Here is a concurrent/recursive quick/merge sort using anonymous inner
classes (the same method is used for
benchmark):
public LargeInteger multiply(LargeInteger that) {
if (that._size <= 1) {
return multiply(that.longValue()); // Direct multiplication.
} else { // Karatsuba multiplication in O(n^log2(3))
int bitLength = this.bitLength();
int n = (bitLength >> 1) + (bitLength & 1);
// this = a + 2^n b, that = c + 2^n d
LargeInteger b = this.shiftRight(n);
LargeInteger a = this.minus(b.shiftLeft(n));
LargeInteger d = that.shiftRight(n);
LargeInteger c = that.minus(d.shiftLeft(n));
Multiply ac = Multiply.valueOf(a, c);
Multiply bd = Multiply.valueOf(b, d);
Multiply abcd = Multiply.valueOf(a.plus(b), c.plus(d));
ConcurrentContext.enter();
try {
ConcurrentContext.execute(ac);
ConcurrentContext.execute(bd);
ConcurrentContext.execute(abcd);
} finally {
ConcurrentContext.exit(); // Waits for all concurrent threads to complete.
}
// a*c + ((a+b)*(c+d)-a*c-b*d) 2^n + b*d 2^2n
return ac.value().plus(
abcd.value().minus(ac.value().plus(bd.value())).shiftWordLeft(n)).plus(
bd.value().shiftWordLeft(n << 1));
}
}
private static class Multiply implements Runnable {
LargeInteger _left, _right, _value;
static Multiply valueOf(LargeInteger left, LargeInteger right) {
Multiply multiply = new Multiply(); // Or use an ObjectFactory (to allow stack allocation).
multiply._left = left;
multiply._right = right;
return multiply;
}
public void run() {
_value = _left.times(_right); // Recursive.
}
public LargeInteger value() {
return _result;
}
};
private void quickSort(final FastTable<? extends Comparable> table) {
final int size = table.size();
if (size < 100) {
table.sort(); // Direct quick sort.
} else {
// Splits table in two and sort both part concurrently.
final FastTable<? extends Comparable> t1 = FastTable.newInstance();
final FastTable<? extends Comparable> t2 = FastTable.newInstance();
ConcurrentContext.enter();
try {
ConcurrentContext.execute(new Runnable() {
public void run() {
t1.addAll(table.subList(0, size / 2));
quickSort(t1); // Recursive.
}
});
ConcurrentContext.execute(new Runnable() {
public void run() {
t2.addAll(table.subList(size / 2, size));
quickSort(t2); // Recursive.
}
});
} finally {
ConcurrentContext.exit();
}
// Merges results.
for (int i=0, i1=0, i2=0; i < size; i++) {
if (i1 >= t1.size()) {
table.set(i, t2.get(i2++));
} else if (i2 >= t2.size()) {
table.set(i, t1.get(i1++));
} else {
Comparable o1 = t1.get(i1);
Comparable o2 = t2.get(i2);
if (o1.compareTo(o2) < 0) {
table.set(i, o1);
i1++;
} else {
table.set(i, o2);
i2++;
}
}
}
FastTable.recycle(t1);
FastTable.recycle(t2);
}
}
Concurrent contexts ensure the same behavior whether or not the execution is performed by the current thread or a concurrent thread. Any exception raised during the concurrent logic executions is propagated to the current thread.
Concurrency
can be locally
adjusted. For example:
LocalContext.enter();
try { // Do not use more than half of the processors during analysis.
ConcurrentContext.setConcurrency((Runtime.getRuntime().availableProcessors() / 2) - 1);
runAnalysis(); // Use concurrent contexts internally.
} finally {
LocalContext.exit();
}
maximum concurrency
.
In other words, if the maximum concurrency is 0
,
concurrency is disabled regardless of local concurrency settings.
Field Summary | |
---|---|
static Configurable<java.lang.Class<? extends ConcurrentContext>> |
DEFAULT
Holds the default implementation. |
static Configurable<java.lang.Integer> |
MAXIMUM_CONCURRENCY
Holds the maximum number of concurrent executors (see Javolution Configuration for details). |
Fields inherited from class javolution.context.Context |
---|
ROOT |
Constructor Summary | |
---|---|
protected |
ConcurrentContext()
Default constructor. |
Method Summary | |
---|---|
static ConcurrentContext |
enter()
Enters a concurrent context (instance of DEFAULT ). |
static void |
execute(java.lang.Runnable logic)
Executes the specified logic by a concurrent thread if one available; otherwise the logic is executed by the current thread. |
protected abstract void |
executeAction(java.lang.Runnable logic)
Executes the specified logic concurrently if possible. |
static ConcurrentContext |
exit()
Exits the current concurrent context. |
static int |
getConcurrency()
Returns the local concurrency. |
static void |
setConcurrency(int concurrency)
Set the local concurrency. |
Methods inherited from class javolution.context.Context |
---|
enter, enter, enterAction, exit, exitAction, getCurrent, getOuter, getOwner, setCurrent, toString |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
public static final Configurable<java.lang.Class<? extends ConcurrentContext>> DEFAULT
javax.realtime.RealtimeThread
for concurrent threads. Alternative (RTSJ) implementations could also use
javax.realtime.NoHeapRealtimeThread
.
public static final Configurable<java.lang.Integer> MAXIMUM_CONCURRENCY
Constructor Detail |
---|
protected ConcurrentContext()
Method Detail |
---|
public static ConcurrentContext enter()
DEFAULT
).
public static ConcurrentContext exit()
java.lang.ClassCastException
- if the context is not a concurrent context.public static void setConcurrency(int concurrency)
local
concurrency. Concurrency is
hard limited by MAXIMUM_CONCURRENCY
.
concurrency
- the new concurrency (0
or negative
number to disable concurrency).public static int getConcurrency()
local
concurrency.
public static void execute(java.lang.Runnable logic)
exit()
of the concurrent context.
logic
- the logic to execute concurrently if possible.
java.lang.ClassCastException
- if the current context is not a
ConcurrentContext
.protected abstract void executeAction(java.lang.Runnable logic)
logic
- the logic to execute.
|
J avolution v5.2 (J2SE 1.5+) | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |