Break out of a recursion in java when the time run out - java

I'm implementing AI for a chess-like game. I intend to use recursion to try all the possible state of the board and choose out the 'best move'.
Because of the time's limit per move, i need to have some mechanism to break out of those recursive procedure whenever the time limit is reached. Of course i can keep checking the time before making a recursion call and break out if the current time is near the limit, but it is a trade-off with the performance of my program.
It would be great if there is a way to break out of those recursive procedure whenever a timer end. However, since i'm new to Java, i don't know if there are any way to do so in java? Can you give an example code? :)

Checking the time, e.g. System.currentTimeMillis() costs about 200 ns per call. However if this is to much for you, you can have another thread set a flag to stop.
There is a mechanism to do this already.
ExecutorService es = Executors.newSingleThreadExecutor();
Future f = es.submit(new Runnable() {
#Override
public void run() {
long start = System.nanoTime();
while(!Thread.interrupted()) {
// busy wait.
}
long time = System.nanoTime() - start;
System.out.printf("Finished task after %,d ns%n", time);
}
});
try {
f.get(1, TimeUnit.SECONDS); // stops if the task completes.
} catch (TimeoutException e) {
f.cancel(true);
}
es.shutdown();
prints
Finished task after 1,000,653,574 ns
Note: you don't need to start/stop the ExecutorService every time.

I don't think there is any nice way of doing this that doesn't involve checking if you can continue.
Even if you did check the time... what happens if you have 8 milliseconds remaining. Can you guarantee that your recursive call will finish in that time? Do you check the time after every little step (this may add a lot of extra overhead)?
One way is to have your execution(recursion) logic running in one thread, and a timer in another thread. When the timer completes, it invokes an interrupt() on your execution thread. In your worker thread, everytime you complete a recursion, you save the state that you need. Then if it gets interrupted, return the last saved state.
That's just a brief description of one way to do it.. by no means the best way

You can use a boolean flag to set when the AI task have to stop.
Create a thread that will run the AI task, this thread will check a boolean variable before each recursive call. To check boolean variable is more efficient than to call a method to get time. Do the parent thread sleep for the limited time. After it wake up, set the boolean flag to stop the child thread.

Related

Heartbeat in Java: timerTask or thread.sleep()?

I want to implement a very simple client to server heartbeat in java. The most simple approach seems to be through sleep. Consider the metacode below.
class MyClass
Thread heartbeatThread = new Thread();
public void() startHeartBeat{
Thread.sleep(4000);
sock.write("H");
}
Is this an adequate solution, or are there pitfalls I'm not considering?
I've also considered using the java.util.Timer.scheduleAtFixedRate approach. Would this be more robust/reliable? If so, why? Here's an example (it's not as clean IMO):
class HeartBeat
{
Timer timer=new Timer();
public void scheduleHeartBeat(int delay, int period) {
timer.scheduleAtFixedRate( new HeartBeatTask(), delay, period);
}
}
class HeartBeatTaskextends TimerTask {
public void run() {
sock.write("H");
}
Will the second approach be granted higher priority?
Firstly, your Thread-based idiom will not schedule at fixed rate without an infinite loop.
That's one disadvantage too: you probably want to set some condition to exit the loop.
You also need to catch InterruptedException when invoking static Thread.sleep.
Another popular idiom for scheduled execution is by using a ScheduledExecutorService.
Find the 3 alternatives below:
Timer
// says "foo" every half second
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
System.out.println("foo");
}
}, 0, 500);
Pros: simple
Cons:
In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up."
Docs here.
Infinite loop
new Thread() {
#Override
public void run() {
while (true) {
// Says "blah" every half second
System.out.println("blah");
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
// nope
}
}
}
}.start();
Pros: super simple. You can vary your recurring delay programmatically.
Cons: Thread.sleep is still
subject to the precision and accuracy of system timers and schedulers.
... and requires catching InterruptedException.
Docs here.
Also:
your infinite loop might require a (somehow potentially cumbersome) breaking condition
no initial delay setting unless applied manually before infinite loop, which would require another try / catch.
Executors
ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor();
es.scheduleAtFixedRate(
new Runnable() {
#Override
public void run() {
// Says "bar" every half second
System.out.println("bar");
}
},
0, 500, TimeUnit.MILLISECONDS);
Pros: this is the most recent feature of the 3. Very simple and elegant - you can also schedule Callables (not at fixed rate though) and re-use the ExecutorService. The documentation for java.util.Timer actually mentions ScheduledThreadPoolExecutor (implementing the ScheduledExecutorService interface) as a "more versatile replacement for the Timer/TimerTask combination".
Cons as documented:
If any execution of this task takes longer than its period, then subsequent executions may start late,
Docs here.
Yes, I don't know how timers are implemented internally, but what I do understand here is, if you use sleep, you will have to handle InterruptedException, and eating up that exception may not be a good practice. moreover timer tasks would be running within its thread space, and you have better control over it.
You can stop the timer any time if you want, In this case, you may not be able to do that
If you use the sleep approach, there are some issues to consider.
One is that the sleep time isn't exact, and you could have drift over time (maybe while your thread is sleeping another application hogs CPU and it takes longer than expected for your thread to send its heartbeat, now the next time the thread sends a heartbeat is delayed), your sleep time will be augmented by various things incrementally (you won't sleep for less than your sleep time but may frequently sleep for a bit more), and those increments will add up over time.
Another is that you could have a problem with the socket, you would have to write code to handle making a new connection.
The thread would need to be well-behaved and respond to interruption, or else be a daemon thread. If it had to share data across threads you'd need to be aware of memory visibility issues.
Using a timer would mean each launching of a task would have a fresh start and you wouldn't be vulnerable to accumulated delays or stale network connections.

End Java threads after a while statement has been run

I am having an issue ending threads once my program my has finished. I run a threaded clock object and it works perfectly but I need to end all threads when the time ´==´ one hour that bit seems to work I just need to know how to end them. Here is an example of the code I have and this is the only thing that runs in the run method apart from one int defined above this code.
#Override
public void run()
{
int mins = 5;
while(clock.getHour() != 1)
{
EnterCarPark();
if(clock.getMin() >= mins)
{
System.out.println("Time: " + clock.getTime() + " " + entryPoint.getRoadName() + ": " + spaces.availablePermits() + " Spaces");
mins += 5;
}
}
}
But when you keep watching the threads that are running in the debug mode of netbeans they keep running after an hour has passed not sure how to fix this. I have tried the interrupt call but it seems to do nothing.
There are two ways to stop a thread in a nice way, and one in an evil way.
For all you need access to the object of the thread (or in the first case a Runnable class that is executed on that thread).
So your first task is to make sure you can access a list of all threads you want to stop. Also notice that you need to make sure you are using threadsafe communication when dealing with objects used by several threads!
Now you have the following options
Interrupt mechanisme
Call Thread.interrupt() on each thread. This will throw an InterruptedException on the thread if you are in a blocking function. Otherwise it will only set the isInterrupted() flag, so you have to check this as well. This is a very clean and versatile way that will try to interrupt blocking functions by this thread. However many people don't understand how to nicely react to the InterruptedException, so it could be more prone to bugs.
isRunning flag
Have a boolean 'isRunning' in your thread. The while loop calls a function 'stopRunning()' that sets this boolean to false. In your thread you periodically read this boolean and stop execution when it is set to false.
This boolean needs to be threadsafe, this could be done by making it volatile (or using synchronized locking).
This also works well when you have a Runnable, which is currently the advised way of running tasks on Threads (because you can easily move Runnables to Threadpools etc.
Stop thread (EVIL)
A third and EVIL and deprecated way is to call Thread.stop(). This is very unsafe and will likely lead to unexpected behavior, don't do this!
Make sure that the loop inside every thread finishes - if it does in all the threads, it does not make sense that there are prints in the output. Just note that what you are checking in each loop condition check if the current hour is not 1 PM, not if an hour has not passed.
Also, your threads garbage collected, which means that the Garbage Collector is responsible for their destruction after termination - but in that case they should not output anything.
A volatile variable shared by all the Threads should help to achieve the goal. The importance of a volatile variable is that each of the Threads will not cache or have local copy but will need to directly read from the main memory. Once it is updated, the threads will get the fresh data.
public class A{
public static volatile boolean letThreadsRun = true;
}
// inside your Thread class
#Override
public void run()
{ // there will come a point when A.letThreadsRun will be set to false when desired
while(A.letThreadsRun)
{
}
}
If two threads are both reading and writing to a shared variable, then
using the volatile keyword for that is not enough. You need to use
synchronization in that case to guarantee that the reading and writing
of the variable is atomic.
Here are links that may help you to grasp the concept:
http://tutorials.jenkov.com/java-concurrency/volatile.html
http://java.dzone.com/articles/java-volatile-keyword-0
If these threads are still running after your main program has finished, then it may be appropriate to set them as daemon threads. The JVM will exit once all non-daemon threads have finished, killing all remaining daemon threads.
If you start the threads like:
Thread myThread = new MyThread();
myThread.start();
Then daemon-izing them is as simple as:
Thread myThread = new MyThread();
myThread.setDaemon(true);
myThread.start();
It's a bad practice to externally terminate threads or to rely on external mechanisms like kill for proper program termination. Threads should always be designed to self-terminate and not leave resources (and shared objects) in a potentially indeterminate state. Every time I have encountered a thread that didn't stop when it was supposed to, it was always a programming error. Go check your code and then step through the run loop in a debugger.
Regarding your thread, it should self-terminate when the hour reaches 1, but if it is below or above 1, it will not terminate. I would make sure that clock's hour count reaches one if minutes go past 59 and also check that it doesn't somehow skip 1 and increment off in to the sunset, having skipped the only tested value. Also check that clock.getHour() is actually returning the hour count instead of a dummy value or something grossly incorrect.
Have you considered using an ExecutorService ? It behaves more predictably and avoids the overhead of thread creation. My suggestion is that you wrap your while loop within one and set a time limit of 1 hr.
Using Thread.interrupt() will not stop the thread from running, it merely sends a signal to you thread. It's our job to listen for this signal and act accordingly.
Thread t = new Thread(new Runnable(){
public void run(){
// look for the signal
if(!Thread.interrupted()){
// keep doing whatever you're doing
}
}
});
// After 1 hour
t.interrupt();
But instead of doing all this work, consider using an ExecutorService. You can use Executors class with static methods to return different thread pools.
Executors.newFixedThreadPool(10)
creates a fixed thread pool of size 10 and any more jobs will go to queue for processing later
Executors.newCachedThreadPool()
starts with 0 threads and creates new threads and adds them to pool on required basis if all the existing threads are busy with some task. This one has a termination strategy that if a thread is idle for 60 seconds, it will remove that thread from the pool
Executors.newSingleThreadExecutor()
creates a single thread which will feed from a queue, all the tasks that're submitted will be processed one after the other.
You can submit your same Runnable tasks to your thread pool. Executors also has methods to get pools to which you can submit scheduled tasks, things you want to happen in future
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(myRunnableTask);
Coming to your question, when you use thread pools, you have an option to shut down them after some time elapsed like this
service.shutdown();
service.awaitTermination(60, TimeUnit.MINUTES);
Few things to pay attention
shutdown() Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
awaitTermination() is waiting for the state of the executor to go to TERMINATED. But first the state must go to SHUTDOWN if shutdown() is called or STOP if shutdownNow() is called.

Repeating threads with loops vs repeating runnable with scheduleAtFixedRate()

final Runnable refresh = new Refresh(params...);
service = Executors.newScheduledThreadPool(1);
service.scheduleAtFixedRate(refresh, 0, 2000, TimeUnit.MILLISECONDS);
// OR
final Thread refresh = new Refresh(params...);
refresh.start(); // In the run() method there is a loop with a sleep of 2000 ms
Which of the above methods to repeat a piece of code are preferred and why?
It is functionally equivalent but the former is more flexible and better separate responsibilities (SRP): a task should not be responsible for how or when it's run...
scheduling at fixed rate is not the same as sleeping. scheduleAtFixedRate calls run every n milliseconds after the start of the previous execution, whereas sleep will start sleeping after the end of the previous execution and thus every following execution will be delayed by the time it took to run. Therefore you should either use scheduleWithFixedDelay or measure the time it takes to run and extract from the sleep time
Using an ExecutorService is better for miltiple reasons. First, as assylias has mentioned, you separate the code from how you choose to run it. Second, an ExcutorService has additional code for managing a thread's lifecycle, execution and priority.
If you using 1 thread, take a look at Timer and TimerTask

Synchronize periodic Task with another Thread

I have the following situation in a Game i'm working:
class GameLogic implements Runnable
{
State state;
private State changeState()
{
//state changes here (note the `private`)
}
// this ticks at each 0.5 seconds
public void run()
{
//code that changes state
changeState();
}
// this will be called by a external Thread at any moment
public void update(Move move)
{
//code that changes state
applyMove(move);
}
private void applyMove(Move move)
{
//state changes here
//state = ... doesn't matter
}
}
The run method above is scheduled to execute at each 0.5 seconds, using a Timer or a ScheduledExecutorService.
The problem is the update method, will be called by another Thread at any moment. So i ask:
1 - What happens if a use synchronized to protect the state field? The timer will wait? How it will compensate for the 'waiting period'?
2 - Is there a better way of doing this? Maybe storing the moves on some queue?
Thanks!
Both Timer and ScheduledExecutorService can execute tasks at fixed rates or with fixed delays between executions. That means, a scheduled task with fixed rates will compensate the running time (including blocking time) of the execution. A scheduled task with fixed delays will not. See the documentation of the following methods for more information:
Fixed rate: Timer.scheduleAtFixedRate and ScheduledExecutorService.scheduleAtFixedRate
Fixed delay: Timer.schedule and ScheduledExecutorService.scheduleWithFixedDelay
There is always a better way. However, the solution looks fine. And as long as it works for you, go with it.
An additional way to deal with this problem is by having the updates coming in from the updating thread go to a Queue or something similar. This way, on each iteration of the state being adjusted you can grab all of the updates from the queue and apply them in the same thread.
Using this method, there would never be any conflict between the updating thread and the game loop thread.
Personally, I would use a while loop that takes advantage of some regulating mechanism instead of scheduling anything. You can use System.nanoTime() in order to apply your updates using time deltas. This would ensure that the execution of logic is not bound to the machine's performance.
There's a brilliant article on the topic here.

Java: Thread/task expiration after specified milliseconds

In Java is there a sane way to have a thread/task run continuously and then end after a specified run time (preferably without using several timers)?
For instance, if I have a TimerTask, there doesn't seem to be a way to schedule that task to end after a certain number of milliseconds or at a specific time with the Timer class.
Sure, I can schedule a task to repeat after a number of milliseconds, but what if I want it to end after one iteration? I have to run another timer within this scheduled task? I'm hoping for a more elegant answer than that.
The answer provided in this question could work, but it is definitely not what I had in mind.
Essentially, I'm looking for something similar to the AutoReset property on C#'s System.Timers.Timer class
You can use an ExecutorService, grab the Future you get and .cancel() it after the time you want:
final Future<Whatever> f = executor.submit(...);
TimeUnit.SECONDS.sleep(xxx);
f.cancel(true);
Or you can have two services: one which executes, another which uses a ScheduledExecutorService for the cancellation.
NOTE: TimerTask depends on the system time, use a ScheduledExecutorService instead.
Simply create another thread and have it time it for when it wants the other thread to stop:
class ThreadTimer implements Runnable {
public void run()
{
Thread.sleep(3000);
MainThread.stopThread();
}
}
class MainThread implements Runnable {
public boolean running = true;
public void run()
{
// thread running code
if(!running)
return;
}
public static void stopThread()
{
running = false;
}
}
Where 3000 is the amount of time in milliseconds from when you want the thread to stop.
Since Thread.stop() is deprecated in Java, the next best way is to only execute the thread if a boolean is set to true. When you call to stop the thread, you're setting that boolean to false, making the code in the thread not run.
Because the void run() doesn't repeat itself and only executes once, if you set the boolean to false, it simply returns run() and halts the thread's execution.
If your task is running in a loop, you can check the current time on each iteration, and terminate the loop if enough time has passed.
Or, if your task involves sleeps, you can set a timer on another thread to call Thread.interrupt on the task.
The only other option would be to set a timer on another thread to call Thread.stop. However, Thread.stop has been deprecated, and there's no safe way to stop a general thread in Java.

Categories

Resources