Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
O
openbis
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
sispub
openbis
Commits
8e422585
Commit
8e422585
authored
13 years ago
by
brinn
Browse files
Options
Downloads
Patches
Plain Diff
Support named callables.
SVN: 24031
parent
41e334c8
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
common/source/java/ch/systemsx/cisd/common/concurrent/TerminableCallable.java
+64
-44
64 additions, 44 deletions
...h/systemsx/cisd/common/concurrent/TerminableCallable.java
with
64 additions
and
44 deletions
common/source/java/ch/systemsx/cisd/common/concurrent/TerminableCallable.java
+
64
−
44
View file @
8e422585
...
...
@@ -21,6 +21,8 @@ import java.util.concurrent.Callable;
import
ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel
;
import
ch.systemsx.cisd.base.exceptions.InterruptedExceptionUnchecked
;
import
ch.systemsx.cisd.base.exceptions.StopException
;
import
ch.systemsx.cisd.base.namedthread.ICallableNameProvider
;
import
ch.systemsx.cisd.base.namedthread.NamedRunnable
;
import
ch.systemsx.cisd.common.utilities.ITerminable
;
/**
...
...
@@ -35,16 +37,16 @@ import ch.systemsx.cisd.common.utilities.ITerminable;
* {@link Thread#interrupt()} and <code>Thread.stop()</code>) should be executed in the
* <var>stoppableExecutor</var>.
* <p>
* <strong>Note: Code executed in the <var>stoppableExecutor</var> must <i>not</i> change
*
variables
or data structures used by several threads or else the problems described in <a
* <strong>Note: Code executed in the <var>stoppableExecutor</var> must <i>not</i> change
variables
* or data structures used by several threads or else the problems described in <a
* href="http://java.sun.com/j2se/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html">"Why is
* <code>Thread.stop()</code> deprecated?"</a> apply to your code! Watch out for static
*
thread-safe
variables like e.g. the ones of type {@link ThreadLocal}!</strong>
* <code>Thread.stop()</code> deprecated?"</a> apply to your code! Watch out for static
thread-safe
* variables like e.g. the ones of type {@link ThreadLocal}!</strong>
* <p>
* The <var>stoppableExecutor</var> is in general supposed to be used for time-consuming
*
algorithmic
code which cannot be interrupted (because it doesn't check the thread's interrupt
*
state). The
simplest case is one big algorithmic block which uses final variables of the caller
*
as input and
delivers its result as return value:
* The <var>stoppableExecutor</var> is in general supposed to be used for time-consuming
algorithmic
* code which cannot be interrupted (because it doesn't check the thread's interrupt
state). The
* simplest case is one big algorithmic block which uses final variables of the caller
as input and
* delivers its result as return value:
*
* <pre>
* public Double call(IStoppableExecutor<Double> stoppableExecutor)
...
...
@@ -93,7 +95,7 @@ import ch.systemsx.cisd.common.utilities.ITerminable;
*
* @author Bernd Rinn
*/
public
final
class
TerminableCallable
<
V
>
implements
Callable
<
V
>,
ITerminable
public
final
class
TerminableCallable
<
V
>
implements
Callable
<
V
>,
ICallableNameProvider
,
ITerminable
{
/** A constant indicating not to wait and to return immediately. */
...
...
@@ -123,6 +125,8 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
/** The time (in milli-seconds) to wait for {@link #terminate()} to finish up. */
private
final
long
timeoutTerminateMillis
;
private
final
String
nameOrNull
;
/** Indicator for why the callable finished. */
public
enum
FinishCause
{
...
...
@@ -169,6 +173,14 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
public
V
call
(
IStoppableExecutor
<
V
>
stoppableExecutor
)
throws
Exception
;
}
/**
* A {@link Callable} that has available a {@link TerminableCallable.IStoppableExecutor} for
* running code that cannot be interrupted but stopped and does know its name.
*/
public
interface
INamedCallable
<
V
>
extends
ICallable
<
V
>,
ICallableNameProvider
{
}
/**
* A role that can perform a clean-up.
*/
...
...
@@ -176,9 +188,8 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
{
/**
* The method that is called whenever the
* {@link ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable#call(
* ch.systemsx.cisd.common.concurrent.TerminableCallable.IStoppableExecutor)} method
* finishes or terminates.
* {@link ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable#call(ch.systemsx.cisd.common.concurrent.TerminableCallable.IStoppableExecutor)}
* method finishes or terminates.
* <p>
* Note that this method is <i>always</i> called, no matter what the cause is. If you want
* to perform clean up only for some causes, check <var>cause</var> first.
...
...
@@ -192,8 +203,7 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
* operations that can fail with an exception.</strong>
*
* @param cause The cause why the
* {@link ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable#call(
* ch.systemsx.cisd.common.concurrent.TerminableCallable.IStoppableExecutor)}
* {@link ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable#call(ch.systemsx.cisd.common.concurrent.TerminableCallable.IStoppableExecutor)}
* method finished.
*/
public
void
cleanUp
(
FinishCause
cause
);
...
...
@@ -212,9 +222,8 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
* terminate the callable.
* <p>
* Convenience wrapper for
* {@link #create(ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable,
* ch.systemsx.cisd.common.concurrent.TerminableCallable.ICleaner, long, long)} with
* <var>waitInterruptMillis</var> set to {@link #DEFAULT_WAIT_INTERRUPT_MILLIS} and
* {@link #create(ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable, ch.systemsx.cisd.common.concurrent.TerminableCallable.ICleaner, long, long)}
* with <var>waitInterruptMillis</var> set to {@link #DEFAULT_WAIT_INTERRUPT_MILLIS} and
* <var>timeoutTerminateMillis</var> set to {@link #WAIT_FOREVER_MILLIS}.
*/
public
static
<
V
>
TerminableCallable
<
V
>
create
(
ICallable
<
V
>
delegate
)
...
...
@@ -223,15 +232,14 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
}
/**
* Factory method that creates a {@link TerminableCallable} with a
<var>delegateWithCleaner</var>
* which is also used to clean up after the call. It sets a time
of
* {@link #DEFAULT_WAIT_INTERRUPT_MILLIS} to wait for {@link Thread#interrupt()} to terminate
* Factory method that creates a {@link TerminableCallable} with a
*
<var>delegateWithCleaner</var>
which is also used to clean up after the call. It sets a time
*
of
{@link #DEFAULT_WAIT_INTERRUPT_MILLIS} to wait for {@link Thread#interrupt()} to terminate
* the callable.
* <p>
* Convenience wrapper for
* {@link #create(ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable,
* ch.systemsx.cisd.common.concurrent.TerminableCallable.ICleaner, long, long)} with
* <var>waitInterruptMillis</var> set to {@link #DEFAULT_WAIT_INTERRUPT_MILLIS} and
* {@link #create(ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable, ch.systemsx.cisd.common.concurrent.TerminableCallable.ICleaner, long, long)}
* with <var>waitInterruptMillis</var> set to {@link #DEFAULT_WAIT_INTERRUPT_MILLIS} and
* <var>timeoutTerminateMillis</var> set to {@link #WAIT_FOREVER_MILLIS}.
*/
public
static
<
V
>
TerminableCallable
<
V
>
create
(
ICallableCleaner
<
V
>
delegateWithCleaner
)
...
...
@@ -245,9 +253,8 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
* separate <var>cleaner</var>.
* <p>
* Convenience wrapper for
* {@link #create(ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable,
* ch.systemsx.cisd.common.concurrent.TerminableCallable.ICleaner, long, long)} with
* <var>waitInterruptMillis</var> set to {@link #DEFAULT_WAIT_INTERRUPT_MILLIS} and
* {@link #create(ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable, ch.systemsx.cisd.common.concurrent.TerminableCallable.ICleaner, long, long)}
* with <var>waitInterruptMillis</var> set to {@link #DEFAULT_WAIT_INTERRUPT_MILLIS} and
* <var>timeoutTerminateMillis</var> set to {@link #WAIT_FOREVER_MILLIS}.
*/
public
static
<
V
>
TerminableCallable
<
V
>
create
(
ICallable
<
V
>
delegate
,
ICleaner
cleaner
)
...
...
@@ -273,8 +280,8 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
}
/**
* Factory method that creates a {@link TerminableCallable} with a <var>delegate</var> that
*
only
runs code which is safe to stop.
* Factory method that creates a {@link TerminableCallable} with a <var>delegate</var> that
only
* runs code which is safe to stop.
* <p>
* <strong>Note: Code executed in the <var>delegate</var> must <i>not</i> change variables or
* data structures used by several threads or else the problems described in <a
...
...
@@ -313,6 +320,9 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
this
.
cleanerOrNull
=
cleanerOrNull
;
this
.
waitInterruptMillis
=
waitInterruptMillis
;
this
.
timeoutTerminateMillis
=
timeoutTerminateMillis
;
this
.
nameOrNull
=
(
delegate
instanceof
ICallableNameProvider
)
?
((
ICallableNameProvider
)
delegate
)
.
getCallableName
()
:
null
;
}
private
void
cleanUp
(
Throwable
throwableOrNull
)
...
...
@@ -338,7 +348,8 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
}
}
private
InterruptedException
getOrCreateInterruptedException
(
InterruptedExceptionUnchecked
stopEx
)
private
InterruptedException
getOrCreateInterruptedException
(
InterruptedExceptionUnchecked
stopEx
)
{
final
InterruptedException
causeOrNull
=
stopEx
.
getCause
();
return
(
causeOrNull
!=
null
)
?
causeOrNull
:
new
InterruptedException
();
...
...
@@ -405,7 +416,7 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
*/
public
Runnable
asRunnable
()
{
return
new
Runnable
()
return
new
Named
Runnable
()
{
public
void
run
()
{
...
...
@@ -417,9 +428,19 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
throw
CheckedExceptionTunnel
.
wrapIfNecessary
(
ex
);
}
}
public
String
getRunnableName
()
{
return
getCallableName
();
}
};
}
public
String
getCallableName
()
{
return
nameOrNull
;
}
/**
* Returns <code>true</code> if the callable is currently running and <code>false</code>
* otherwise.
...
...
@@ -436,7 +457,7 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
{
return
threadGuard
.
isCancelled
();
}
/**
* Returns <code>true</code> if the callable has already started running.
*/
...
...
@@ -473,10 +494,9 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
/**
* Cancels the callable if it is not yet running.
*
* @param mayInterruptIfRunning If <code>true</code> and the callable is running, interrupt
* its thread. Otherwise, do nothing.
* @return <code>true</code>, if the callable is cancelled and <code>false</code>
* otherwise.
* @param mayInterruptIfRunning If <code>true</code> and the callable is running, interrupt its
* thread. Otherwise, do nothing.
* @return <code>true</code>, if the callable is cancelled and <code>false</code> otherwise.
*/
public
boolean
cancel
(
boolean
mayInterruptIfRunning
)
{
...
...
@@ -485,10 +505,10 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
/**
* Terminates this {@link TerminableCallable}. A convenience wrapper for
* {@link #terminate(long)} with <var>timeoutMillis</var> set to
<var>timeoutTerminateMillis</var>
* as set in the factory method (see
* {@link #create(ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable,
*
ch.systemsx.cisd.common.concurrent.TerminableCallable.ICleaner, long, long)}
.
* {@link #terminate(long)} with <var>timeoutMillis</var> set to
*
<var>timeoutTerminateMillis</var>
as set in the factory method (see
* {@link #create(ch.systemsx.cisd.common.concurrent.TerminableCallable.ICallable,
ch.systemsx.cisd.common.concurrent.TerminableCallable.ICleaner, long, long)}
* .
*
* @return <code>true</code>, if the callable is confirmed to be terminated and cleaned up
* successfully in due time, or <code>false</code>, if a timeout has occurred.
...
...
@@ -500,11 +520,11 @@ public final class TerminableCallable<V> implements Callable<V>, ITerminable
}
/**
* Tries to terminate this {@link TerminableCallable}. Note that this is a synchronous call
*
that
returns only when either the callable has been terminated or finished or when a timeout
*
has
occurred. Note also that even when providing <var>timeoutMillis</var> as 0, this method
*
may
wait up to <var>waitInterruptMillis</var> milli-seconds for the
*
{@link Thread#interrupt()}
call to terminate the callable.
* Tries to terminate this {@link TerminableCallable}. Note that this is a synchronous call
that
* returns only when either the callable has been terminated or finished or when a timeout
has
* occurred. Note also that even when providing <var>timeoutMillis</var> as 0, this method
may
* wait up to <var>waitInterruptMillis</var> milli-seconds for the
{@link Thread#interrupt()}
* call to terminate the callable.
*
* @param timeoutMillis The method will wait at most this time (in milli-seconds).
* @return <code>true</code>, if the callable is confirmed to be terminated or finished, or
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment