Java sleep only one object - java

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();

Related

Timer on if statement?

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.

How do I make the main method wait until my Swing timer completes execution?

I'm presently working on a traffic control for a cross junction. I created a method that processes the countdown for 4 bulbs. The countdown is working fine. The name of the method is start(int lane) so I want something to place the method in a loop to run 10 times like:
while (counter<10){
int x = getnextlane(); // first choose a lane to run its timer
start(x); //start running the lane's timer countdown to 0 from 10
//I want the main thread to wait till the start(x) completes before it goes to the next line
system.out.println("lane "+x+" is running");
}
I found out that when I run the Gui, the countdown starts but before it gets to zero, the println statement completes before it. That is:
output:
lane 1 is running
lane 2 is running
lane 3 is running
lane 4 is running
lane 1 is running
lane 2 is running
lane 3 is running
lane 4 is running
lane 1 is running
lane 2 is running
I want to make sure that the timer completes before the main thread jumps to the next line.
A swing application is a GUI application. GUI applications are event-driven.
The right way of doing this type of thing in an event-driven application is by using events.
So, you are supposed to start your timers and then return from your current method (which you described as "the main method") to swing, so that swing can continue processing events.
When a timer fires, you invoke some function which checks whatever you want to check, and if all the necessary conditions are met, you invoke another function which performs some job as a result of the fact that all these conditions have been met.
In a GUI application you never sit somewhere waiting for something to happen, because while you are doing that, your entire GUI is frozen.
Also, in theory you could start threads to do the job, but then you would need to be careful because most GUIs are not thread safe, and this includes swing, so you will not be able to invoke any GUI methods from other threads.
You can use Thread, threads scheduling is controlled by thread scheduler.So, you cannot guarantee the order of execution of threads under normal circumstances. also, you can wait till first thread does not complete.
However, you can use join() to wait for a thread to complete its work.
in your case, you can put swing timer to Thread & do Join.
Thread t = new Thread(
new Runnable() {
public void run () {
while (counter<10){
int x = getnextlane();
// start(x);
system.out.println("lane "+x+" is running");
}
}
}
);
t.start();
t.join();

If there's only one thread running(main) and sleep(1000) is invoked, will the thread sleep for exactly 1 second or atleast 1 second?

In the below code:
class Test {
public static void main(String [] args) {
printAll(args);
}
public static void printAll(String[] lines) {
for(int i=0;i<lines.length;i++){
System.out.println(lines[i]);
Thread.currentThread().sleep(1000);
}
}
}
Will each String in the array lines output:
With exactly 1-second pause between lines?
With at least 1-second pause between lines?
Approximately 1-second pause. The thread can be woken up beforehand and you'll get an InterruptedException, or the thread can sleep for 1000ms and then not get to run immediately, so it will be 1000ms + microseconds (or more, if there are higher priority threads hogging the CPU).
You're also calling it wrong. It's Thread.sleep(1000);, as a static method it always acts on the current thread and you can't make other threads sleep with it.
So it will sleep for exactly 1 second to the best of it's knowledge. The thread.sleep method is not perfect. See this and other related questions:
https://stackoverflow.com/a/18737109/4615177
Calling Thread.sleep(1000) method, put the current executing thread in waiting state for the specified time. As per your program, it seems only a single threaded program hence,while The calling thread is in waiting state, no other thread is in running state, so after 1000 ms your thread will get chance to execute almost after 1000ms but not sure for other application where no of threads are going to execute.
Some points about Thread.sleep
1. it is always the current thread that is put to sleep
2. the thread might not sleep for the required time (or even at all);
the sleep duration will be subject to some system-specific granularity, typically 1ms;
3. while sleeping, the thread still owns synchronization locks it has acquired;
4. the sleep can be interrupted (sometimes useful for implementing a cancellation function);
5. calling sleep() with certain values can have some subtle, global effects on the OS
So at the end you can each String output will be with at least 1-second pause between lines.
And you calling it wrong. It is a static method..:)
It'll sleep for at least 1 second if not interrupted by some other thread. If some other thread interrupts it, InterruptedException will be thrown.
Ideally, it'll sleep for 1 second, once that time has elapsed, it will wait for it's turn to get into running state again.
Read the documentation. (Why did no one else say that?) The javadoc for Thread.sleep() says,
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
That's pretty vague, but that's all the guarantee you will get. The exact behavior will depend on what operating system you are running and probably on what JVM you are running.
An application that requires precise timing is called a real-time application, and there are special real-time operating systems (RTOS) that will tell you within how many microseconds of its scheduled time an event actually will occur. you can even get real-time versions of Java to run on your RTOS. http://en.wikipedia.org/wiki/Real_time_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.

How to pause a thread in java?

Consider the following code:
while(true) {
someFunction();
Thread.sleep(1000);
}
What I want is that, someFunction() be called once every 10 seconds. But this is not the case. It is being called every second. I tried Thread.wait(1000), but even that doesnt help. I removed of the while part, just kept the body, and at the end wrote :
Thread.start();
But it throwed an exception. Is there any other solution to this?
It's being called every second because you're sleeping for 1000 milliseconds, aka 1 second.
Change it to Thread.sleep(10000) and that'll be better for you.
Alternatively, use
Thread.sleep(TimeUnit.SECONDS.toMillis(10));
which means you don't have to do the arithmetic yourself. (Many APIs now take a quantity and a TimeUnit, but there doesn't appear to be anything like that for Thread.sleep unfortunately.)
Note that this will make the thread unresponsive for 10 seconds, with no clean way of telling it to wake up (e.g. because you want to shut it down). I generally prefer to use wait() so that I can pulse the same monitor from a different thread to indicate "I want you to wake up now!" This is usually from within a while loop of the form
while (!shouldStop())
EDIT: tvanfosson's solution of using a Timer is also good - and another alternative is to use ScheduledExecutorService which can be a bit more flexible (and easier to test).
Thread.sleep() takes the number of miliseconds to sleep. Thus, calling Thread.sleep(1000) sleeps 1000 miliseconds, which is 1 second. Make that Thread.sleep(10000) and it will sleep 10 seconds.
1 second is 1000 milliseconds, so if you want 10 seconds = 10 * 1000 = 10000 milliseconds
e.g.
try {
long numMillisecondsToSleep = 5000; // 5 seconds
Thread.sleep(numMillisecondsToSleep);
} catch (InterruptedException e) { }
What you probably want to do is use a Timer and set up a scheduled invocation of the function rather than sleeping. If you need more exactness with regard to the interval, you can keep track of how long it has been since the last run and adjust the new timer to keep your interval from drifting. See an example of a simple timer in this tutorial.
I won't go into detail about the issue with regard to the precision of the argument, since #Jon has already covered that -- you need milliseconds rather than seconds.
Consider 1000 milliseconds is 1 second. For that you should use Thread.sleep(10000) for acheiving pause your thread in 10 seconds. You can also use looping with how many seconds to wait your thread.
Ex. suppose you want to pause your thread in half-an-hour( 30 minutes). Then use,
for(i=0;i<1800;i++)
{
Thread.sleep(1000);
}
It will pause your thread in 30 minutes.
What I want is that, someFunction() be
called once every 10 seconds.
Then why do you call Thread.sleep() with 1000 as parameter? That's in milliseconds, so you're explicitly saying "wait 1 second".

Categories

Resources