Timer on if statement? - java

I’m working on a Finch robot project on detecting objects and in one of the methods, I have to do an if statement for if the Finch has detected an object within 5 seconds, would I need a timer class for this? Please help. (New to Java)
IF Finch detects an object <= 5 seconds, stop and turn LED to blue ELSE wait 1 second and keep moving in random direction (I’ve already done this)
Edit: my code so far:
public static void ObjectEncountered() {
while(true) {
if(myfinch.isObstacle()== true){
myfinch.setLED(0, 0, 255);
myfinch.setWheelVelocities(0, 0);
}
else {
myfinch.setLED(0, 0, 0);
random();
}
}
}

We'd need more code to answer. If your method for detecting objects always returns right away, then it is easy enough to stay in a loop until System.currentTimeMillis() shows a number more than 5000 greater than when you started. However, if your method to detect objects doesn't return until it detects something, possibly 20 seconds later, then you will need some asynchronous programming to be able to turn your LED to blue at the 5-second point.
That approach would involve spinning off another thread to call the detect method, then waiting until either it detects something or 5 seconds elapses. You might use a BlockingQueue for the communications from one thread to the other, since that also offers a timed wait. If you don't care about detected objects after the 5 seconds, you can have the main thread interrupt the detect thread, which will let it shut down gracefully.

Related

Is Executors.newSingleThreadScheduledExecutor() applicable for multiple objects?

Im making a small game where space-ships fire in intervalls of x seconds.
In this method Im spawning lasers the enemies can fire. In order to time their shots
Im using
Executors.newSingleThreadScheduledExecutor();
but Im not sure if that´s right when there can be multiple enemy-space ships on the board at once.
(Since its using one thread and then waits x seconds before using that thread for that task again).
So summarized: is this the right way to time an event for multiple objects or is it only working for one object a a time.
There are some more performance optimized versions, but the aproach is fine for the beginning.
ScheduledFuture<?> future = s.scheduleAtFixedRate(shoot, 0, enemy.getRate(), TimeUnit.SECONDS);
Will be scheduled once impediatly, and then every getRate() seconds until you call future.cancel().
Only one shot is evaluated at a single moment, thats fine if the caclculation is rather quick, and you don't call Thread.sleep() in the Runnable.

Using threads to break out of game loop

I am working on a console game in Java that has 10 rounds that are 2 minutes each. I need a way to use threads to alert the user every 30 seconds that have passed and then override the main method and break the user out of the game loop after two minutes have passed.
How could I use threads to break the main loop out of one function and return the user to another one?
Thanks
You can either use non blocking API (that give you for example the current state of the keyboard/mouse rather than block) in a loop and just not run the next iteration when the time out occured.
Or you can interrupt the thread if this one is blocked/sleeping on a blocking API calling this the interupt method of that thread:
refToThreadToInterupt.interupt();
This will generate an InteruptedException if the thread is blocked or set the interupt flag to true otherwise. Can be checked by the thread with:
refToThreadToInterup.isInterupted();
As you have no idea as of what the thread is doing when you interupt it, you don't know if you get the exception or if the boolean will just be set to true, so you have to deal with both cases.

Java sleep only one object

I have a program, where there are some dots flying on a screen.
I need to do something where one dot is sleeping for 2 seconds.
public void move(Dot dot) {
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
fun();
}
Sleep cause the whole program stops for 2 seconds. How to do it for only one dot?
I would change my Dot class to include a Timer. The move function could then decide based on some parameters if the Timer should be activated. Upon the first tick, disable the Timer. The Timer could set a Boolean which is queried when deciding whether moving the dot is allowed or not.
Timer Class
If I'm understanding your question correctly, your game looks something like this:
move(dot1); // You want this to move instantly
move(dot2); // You want this dot to sleep for 2 seconds, and then move
move(dot3); // You want this dot to move instantly
The thing with program execution is that everything happens in order, one line of code after the other. So move(dot2) will only get executed once move(dot1) has finished, and move(dot3) will only get executed once move(dot2) has finished. In your example, you've changed move(dot2) to sleep for 2 seconds, which means that move(dot2) will only complete 2 seconds later, which means that move(dot3) will only start 2 seconds later, once move(dot2) has finished. In fact, because the entire rest-of-the-program only resumes once move(dot2) has finished, the entire program will sleep for 2 seconds like you mentioned.
However, there is exception to this. Everything mentioned above is only applicable for a single thread. Within a thread, all code will get executed sequentially, one after the other. However, if you create multiple threads, and give each thread a different piece of code to run, all the different threads will run in parallel. Even if Thread-A hits a piece of code that takes a long time to run (such as Thread.sleep(1000)), Thread-B will still be able to run its code without waiting around.
This is a powerful feature that can be applied to your game. You want move(dot2) to sleep for 2 seconds before moving, but you don't want the rest of the game to wait around for the 2 seconds. Solution: kick off a new thread, tell it to run move(dot2), and you main thread can immediately start executing the rest of your code.
Example:
move(dot1); // will complete instantly
new Thread(() -> move(dot2, 2000)).start(); // Creates a new thread, tells it to execute move(dot2, 2000), and start it off
move(dot3); // will complete instantly, as soon as move(dot2...) has been started off, without waiting for it to finish
Some more details about Java multi-threading
P.S. You mentioned a 2 second sleep, but your code is hard-coding the sleep to 1000ms, which is 1 second. If you want it to sleep for 2 seconds, you should change it to 2000ms.
Also, if you want some dots to move instantly and others to wait for 2 seconds, you should convert the 2000 into an input argument. That way, you can call move(dot1, 0) so that it will finish instantly, and move(dot2, 2000) so that it will finish after 2 seconds.
I think your problem is you're calling sleep() in your application-thread. If you do this your whole application is stopping for two seconds.
You could start a new Thread in which you're controlling your dot. Something like that:
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// control, move your dot or sleep here
}
});
t.start();

Run thread in background in java

I'm writing a chess program in java. So far things are coming along fine but I do have a problem with updating my UI.
Here's a snippet of code from class ChessBoard which extends JPanel. This is called when a user tries to make a move:
if ( isLegalMove( aMove ) ) { // If the move's legal
makeMove( aMove ); // Make that move
select = null; // Reset some info
drag = null;
toggleTurn(); // Change turns
generateMoves( 0 ); // Get legal moves for CPU
repaint(); // Redraw board
thread.run(); // Run chess algorithm
}
The thread is calling "run" on my instance of ChessBoard. The algorithm that finds the move can take several seconds to decide on a move.
I would like for my UI to update to reflect the user's move and then run the algorithm. That's why I run the algorithm on a separate thread. But my UI is not being updated until the computer also makes a move.
So if the user clicks a space to send a piece there, the screen freezes and then all of a sudden the piece has moved but the computer has moved also and it is again the player's turn.
Any help will be greatly appreciated.
thread.run() is going to execute the code in the thread's run method on the current thread. You want thread.start().
Relevant JavaDoc
The repaint method doesn't actually repaint immediately. It basically tells the JPanel that it ought to repaint itself soon. Then you go ahead on the same thread and calculate the AI's move, which will freeze the window because Swing isn't multi-threaded.
First, threads are not re-entrant (I'll explain that in a moment).
thread.run() is not causing the thread to execute in a separate thread, it's just call the run method of the thread (within the current Threads context.
What you need to do is set up a condition loop within your Thread that you can trigger in order to execute the logic you need.
public class ChessThread extends Thread { // I prefer Runnable, that's me
protected static final Object NEXT_MOVE_LOCK = Object();
public ChessThread() {
setDaemon(true); // This will allow the JVM to exit without the need to terminate the thread...
}
public void doNextMove() {
// Notify the "wait" that we want to continue calculating the next move
synchronized (NEXT_MOVE_LOCK) {
NEXT_MOVE_LOCK.notify();
}
}
public void run() {
while (true) {
// Wait for the "next move" request
synchronized (NEXT_MOVE_LOCK) {
try {
NEXT_MOVE_LOCK.wait();
} catch (InterruptedException exp) {
}
}
// Calculate the next move...
}
}
}
Now, Threads are non-reentrant, this means that once the run method has complete, that instance of the Thread can not be restarted.
Hence using thread.start() more then once will not work (can't remember if it throws an exception or not) (hence the reason I prefer Runnable)
So. What you want to do, is start the Thread when your program loads and when you need to, call thread.doNextMove() to cause it calculate the what ever it is you need.
Now, also remember, Swing is not Thread safe. That is, you should NEVER update the UI from any Thread other than the Event Dispatching Thread (or EDT)
You might also want to have a read through Concurrency in Swing
Oh and Concurrency in Java

Constantly checking a port without a while loop

In a program (Java) I'm making I need to check for a specific pin in the parallel port. Whenever that pin goes from logical 0 to 1 (a positive edge clock) I have to read the data on the port and save it. This happens about every 10ms but can vary a little.
To do this I made a separate thread with a while loop that is constantly checking the port, but this makes the processor go nuts and I know it's because of the while loop. My question is, how can I constantly scan the port without using a processor intensive while loop? The program doesn't know precisely when a pin change will happen, only that it happens around every 10ms.
Fire a thread which is scheduled to execute the given Runnable at a fixed rate. You can use Timer#scheduleAtFixedRate() or ScheduledExecutorService#scheduleAtFixedRate() for this. The last one is preferred.
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new PortScanner(), 0, 10, TimeUnit.MILLISECONDS); // Run every 10 ms.
Where PortScanner can look like this:
public class PortScanner implements Runnable {
#Override
public void run() {
// Scan port here.
}
}
Don't forget to call scheduler.shutdown() at the moment your application exits, else the thread may hang.
There might be a better solution, but worst case you could just Thread.sleep for 1-2ms every iteration of the while loop.
It is really tricky to catch hardware interrupts when your code is not running as a part of operating system. What you can do is to put Thread.Sleep ( 5 ). This will sleep for 10 milliseconds, and will let the other threads run or just keep CPU idle and cool. Having 5 ms delay should be enough to ensure won't miss any clock ticks.
This would work when your clock is alternating between 10 ms high and 10 ms low. For other patterns you have to adjust the parameter accordingly.

Categories

Resources