public class EventTimerThread extends java.lang.Object implements EventTimerThread_ifc, java.io.Closeable, InfoAppend
start()
and close()
are used from instances of EventWithDst
,
TimeOrder
and TimeOrder
internally.
They should not be invoked by an application directly.
But if any other event derived from EventObject
is used then the methods
setStdEventProcessor(EventConsumer)
, storeEvent(EventObject)
and maybe removeFromQueue(EventObject)
should be used.
EventTimerThread myExecutionThread = new EventTimerThread("thread-name"); myExecutionThread.start();On end of the application
close()
should be invoked to end the thread.
EventWithDst
from any other thread use this instance as argument for the event:
MyEventWithDst event = new MyEventWithDst(source, dst, myExecutionThread); //or: event.occupy(source, dst, myExecutionThread, ...) event.sendEvent();To add any other type of
EventObject
you should set a setStdEventProcessor(EventConsumer)
.
Then use
myExecutionThread.storeEvent(eventObject);This class is used as time manager too. It manages and executes
TimeOrder
which are used especially for StateMachine
,
but it can execute TimeOrder
in this thread too. To add a timeout event or a time order
use the methods of the TimeOrder.activateAt(long)
etc:
TimeOrder myTimeOrder = new TimeOrder("name", myExecutionThread) { QOverride protected void executeOrder(){ ...execution of the time order ...} }; ... myTimeOrder.activate(100); //in 100 milliseconds.That routine invokes the routine
addTimeEntry(TimeOrder)
of this class.
ConcurrentLinkedQueue
which is thread-safe to enqueue events
from any thread with the method storeEvent(EventObject)
.
Then Object.notify()
is called to weak up the thread if it sleeps. Then the all stored events are dequeued
and its execution routine of EventConsumer.processEvent(EventObject)
is invoked. The events are processed one after another.
The execution routine is usual a StateMachine
but any other EventConsumer
is able to use too.
TimeOrder
are stored in another ConcurrentLinkedQueue
.
The absolute time of the next execution is stored in the internal value of timeCheckNew
. The thread sleeps either
till this time is expired or till an event is given. If the time is expired all stored time orders are checked
whether its time is elapsed. Then either the EventConsumer.processEvent(EventObject)
is invoked
if an TimeOrder
is given or a TimeOrder
has a destination. Elsewhere the TimeOrder#doExecute
is invoked to execute the TimeOrder#executeOrder()
in this thread.
removeFromQueue(EventObject)
is invoked if an event should be EventWithDst.occupyRecall(EventSource, boolean)
. That is if the event should be used
newly.
TimeOrder
can be removed from execution with the method TimeOrder.deactivate()
.
Adequate is done with removeTimeEntry(TimeOrder)
.Modifier and Type | Field and Description |
---|---|
protected boolean |
bThreadRun |
private int |
ctWaitEmptyQueue |
private int |
debugPrint
Bit variable to control some System.out.printf debug outputs.
|
(package private) int |
debugPrintViewDelayed
Only for inspector or debug access: Use it to show delaying.
|
private int |
delayMax
The delay [ms] for one step if nothing is to do.
|
private EventConsumer |
eventProcessor |
private java.util.concurrent.atomic.AtomicBoolean |
extEventSet
Set if any external event is set.
|
protected int |
maxCtWaitEmptyQueue |
private boolean |
preserveRecursiveInfoAppend |
private java.util.concurrent.ConcurrentLinkedQueue<TimeOrder> |
queueDelayedOrders
Queue of orders which are executed with delay yet.
|
private java.util.concurrent.ConcurrentLinkedQueue<java.util.EventObject> |
queueEvents
Queue of orders which are executed with delay yet.
|
private java.util.concurrent.ConcurrentLinkedQueue<TimeOrder> |
queueOrdersToExecute
Temporary used instance for orders ready to execute while
runTimer organizes the delayed orders. |
private java.lang.Runnable |
runTimer
Instance as Runnable contains invocation of
stepThread()
and the Object.wait() with the calculated timeWait. |
protected boolean |
startOnDemand |
protected char |
stateThreadTimer
State of the thread, used for debug and mutex mechanism.
|
protected java.lang.String |
threadName |
protected java.lang.Thread |
threadTimer
The thread which executes delayed wake up.
|
protected long |
timeCheckNew
timestamp for a new time entry.
|
private long |
timeSleep
The time on start waiting
|
static java.lang.String |
version
Version, license and history.
|
Constructor and Description |
---|
EventTimerThread(java.lang.String threadName)
Creates the Manager for time orders.
|
Modifier and Type | Method and Description |
---|---|
char |
addTimeEntry(TimeOrder order)
Adds a timeout event or a time order with given execution time.
|
private boolean |
checkEventAndRun()
Applies an events from the queue to the destination in the event thread.
|
private int |
checkTimeOrders()
Check all time orders whether there are expired, or if not calculate the next time to check.
|
void |
close()
Should only be called on end of the whole application to finish the timer thread.
|
protected void |
createThread_()
This operation can be overridden if another thread organization,
especially another
stepThread() should be used. |
char |
getState()
Returns the current state of the thread.
|
java.lang.CharSequence |
infoAppend(java.lang.StringBuilder u)
Info for debugging
This operation can be overridden for another thread organization. |
boolean |
isBusy()
Checks whether the thread is busy.
|
boolean |
isCurrentThread()
Returns true if the current thread is the thread which is aggregate to this EventThread.
|
void |
notifyTimer()
Wakes up the
runTimer queue to execute delayed requests. |
boolean |
removeFromQueue(java.util.EventObject ev)
Removes this event from its queue if it is in the event queue.
|
boolean |
removeTimeEntry(TimeOrder order)
Removes a time order, which was activated but it is not in the event execution queue.
|
void |
setStdEventProcessor(EventConsumer eventProcessor)
Sets the event processor for all events which are not type of
EventWithDst . |
void |
start()
Creates and starts the thread.
|
private void |
startOrNotify() |
protected int |
stepThread()
The core run routine for the timer thread.
|
boolean |
storeEvent(java.util.EventObject ev)
Stores an event in the queue, able to invoke from any thread.
|
java.lang.String |
toString() |
protected void |
wakeup_()
Wakes up the waiting thread because a new event or time entry is enqueues.
|
public static final java.lang.String version
TimeOrder.bHoldTimeorder
to change data in time order, prevent processing.
org.vishia.gral.base.GralMng
as graphic thread.
Hence some stuff is now protected, only a few operations are overridden, see there.
All non overridden operations are set to final now here.
delayMax
now also valid if no time order was processed.
Before, it was 1000 days. This is not problematically for event processing,
because an event wakes up the wait by runTimer
.Object.notify()
but it is stupid on debugging.
isBusy()
timeCheckNew
OrderListExecuter
org.vishia.gral.base.GralGraphicThread
,
this class is the base class of them now. The algorithm is able to use outside of that graphic too.
private int debugPrint
int debugPrintViewDelayed
protected final java.lang.String threadName
protected java.lang.Thread threadTimer
private EventConsumer eventProcessor
private final java.util.concurrent.ConcurrentLinkedQueue<java.util.EventObject> queueEvents
private final java.util.concurrent.ConcurrentLinkedQueue<TimeOrder> queueDelayedOrders
private final java.util.concurrent.ConcurrentLinkedQueue<TimeOrder> queueOrdersToExecute
runTimer
organizes the delayed orders.
This queue is empty outside running one step of runTimer().protected boolean bThreadRun
private int delayMax
protected long timeCheckNew
#addTimeOrder(TimeEvent, long)
and the wait in the #run()
operation.
The default value is 10 seconds after now, because no time order may be added.
10 sec is the limited delay to run one step.private long timeSleep
protected char stateThreadTimer
addTimeEntry(TimeOrder)
with delayed order.private final java.util.concurrent.atomic.AtomicBoolean extEventSet
protected boolean startOnDemand
private int ctWaitEmptyQueue
protected int maxCtWaitEmptyQueue
private boolean preserveRecursiveInfoAppend
private java.lang.Runnable runTimer
stepThread()
and the Object.wait()
with the calculated timeWait.
Note desired for overridden implementation.public EventTimerThread(java.lang.String threadName)
start()
at begin and close()
on end of an application.executesTheOrder
- true then the method #step(int, long)
need not be called (not necessary) because the TimeOrder
are executed from the threadTimer already.
#step(int, long)
have to be called cyclically from any other thread.public final void setStdEventProcessor(EventConsumer eventProcessor)
EventWithDst
. That events are executed with
the given eventProcessor's method EventConsumer.processEvent(EventObject)
.
This eventProcessor is not used for EventWithDst
. They need a destination or they should be a TimeOrder
.
eventProcessor
- the event processor.public final void start()
#storeEvent(EventCmdtype)
was called.
In that case the thread stops its execution if the event queue is empty and about 5 seconds
are gone.protected void createThread_()
stepThread()
should be used.
Then just another Runnable implementation for the thread is used.public final boolean storeEvent(java.util.EventObject ev)
storeEvent
in interface EventThread_ifc
ev
- private void startOrNotify()
protected void wakeup_()
org.vishia.gral.base.GralMng
.public void close()
ConnectionExecThread
is given as Argument of @link EventTimerThread#TimeOrderMng(ConnectionExecThread)
and this instance implements the @link ConnectionExecThread#isRunning()
method. If that method returns false
then the timer thread is finished too.
close
in interface java.io.Closeable
close
in interface java.lang.AutoCloseable
Closeable.close()
public final char addTimeEntry(TimeOrder order)
EventTimerThread_ifc
TimeOrder.activateAt(long)
etc. That routines calls this method internally already.
Therefore this method should not be called by an application directly. It is only a rule to implement.addTimeEntry
in interface EventTimerThread_ifc
public final boolean removeTimeEntry(TimeOrder order)
ConcurrentLinkedQueue
.removeTimeEntry
in interface EventTimerThread_ifc
order
- public final boolean removeFromQueue(java.util.EventObject ev)
EventWithDst
is found in the queue, it is designated with stateOfEvent = 'a'
This operation is thread safe. Either the event is found and removed, or it is not found because it is
either in execution yet or it is not queued. The event queue is a ConcurrentLinkedQueue
.removeFromQueue
in interface EventThread_ifc
ev
- The event which should be dequeuedpublic boolean isBusy()
EventThread_ifc
TimeOrder
waits for its finishing. If an execution remains in process because debugging, this method returns true.isBusy
in interface EventThread_ifc
private boolean checkEventAndRun()
private int checkTimeOrders()
queueDelayedOrders
regarding changing also for and because TimeOrder.activateAt(long, long)
, which uses this as mutex.
#evDst()
is given the EventConsumer.processEvent(java.util.EventObject)
is called
though this instance may be a timeOrder. This method can enqueue this instance in another queue for execution
in any other thread which invokes then TimeOrder#doExecute()
.
TimeOrder
and the #evDst is not given by constructor
then the TimeOrder#doExecute()
is called to execute the time order.
#activate(int)
etc. enqueues this instance newly
with a new time for elapsing. It is executed newly therefore.protected final int stepThread()
public final boolean isCurrentThread()
#run()
method has called this method.isCurrentThread
in interface EventThread_ifc
public final char getState()
public void notifyTimer()
runTimer
queue to execute delayed requests.
public java.lang.CharSequence infoAppend(java.lang.StringBuilder u)
infoAppend
in interface InfoAppend
u
- if not null then the info is appended to u, u is returned.
public java.lang.String toString()
toString
in class java.lang.Object