I have a while loop that needs to repeat once a second, and I have no idea how to do that. I have never even used Java's time module or whatever it is called.
The basic loop is shown below. Can anyone give me a tip on how to do this?
while (!isOver()) {
// do some work
}
Maybe this code snippet can help you out. It´s a scheduled timertask that will repeat the run() method every 1 second. Your can add whatever you want there.
TimerTask timerTask = new TimerTask()
{
public void run()
{
.... //Whatever inside your loop will be executed every second
}
};
....
Timer timer = new Timer();
timer.scheduleAtFixedRate(timerTask, 0, 1000);
I would probably use a thread, though depending on how fast your computer is, and how much work it needs to do for each iteration of the loop, it might not be perfect.
Each program has one thread at all times. If it doesn't, it's not a process. This is your main thread, it comes to "life" when your program starts, and dies when your program terminates. There is a static method on Thread called sleep(int ms). This suspends the processing of the thread until it's parameter (ms) milliseconds have elapsed. So Thread.sleep(1000) would suspend the thread for one second, then resume.
Suspending the main thread for one second each time looks like this:
while(!isOver()) {
// Do stuff
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Deal with exception here
}
}
Hope this helps. There is another way to create threads, but for this purpose it's way too long and drawn out..
PS You need the try/catch because sometimes the System can interrupt your thread, and that will cause an exception. A simple e.printStackTrace() should let you know when it happens, but you might want to deal with it more explicitly for any production application.
while (!isOver()) {
// do some work
try {
Thread.sleep(1000); /* 1000ms or 1 second */
} catch(InterruptedException e) {
// handle
}
}
private void time() {
while (! isOver) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
//Do nothing, just loop
}
}
}
And then start that on another thread so your main thread will continue:
new Thread(this::time).start();
As you can see there are tons of ways to accomplish what you are looking to do. Here is another way. I tend to shy away from Timers if your code can throw exceptions as it will stop the Timer from running again. Something like this will work with a few less gotchas.
ScheduledExecutorService e = Executors.newSingleThreadScheduledExecutor();
e.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
}
}, 0, 1, TimeUnit.SECONDS);
}
Or if you wanted to do a sleep you could try:
while(!isOver) {
//DO WORK
try {
//Be careful if you are holding any Locks they will not be released
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
//Do nothing, just loop
}
}
Related
After reading several SO posts on how to kill a Java thread, I fairly understand why stop is unsafe and how to handle the graceful stop.
But the solutions are targeting towards UI threads where repainting is the problem and not really a long running - blocking process executed by a thread.
Links:
How do you kill a Thread in Java?
https://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
One precise point that I fail to understand from the solutions or examples is what is the long-running-part the samples are trying to simulate.
Eg: In this following code, what if I set the interval to INT.MAX.
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
thisThread.sleep(interval); // This might take forever to complete,
// and while may never be executed 2nd time.
synchronized(this) {
while (threadSuspended && blinker==thisThread)
wait();
}
} catch (InterruptedException e){
}
repaint();
}
}
public synchronized void stop() {
blinker = null;
notify();
}
The reason am asking for this use case is that, I have a bug in a legacy code base that runs another executable in a Thread.
Now the ask if the user wishes to stop the thread, we would need to kill this thread, and the executable which is part of this thread automatically gets killed.
The way you stop a thread is by asking it - nicely - to stop. It's up to the code the thread is running to listen for and act on that request.
Specifically, the way you do it is to interrupt the thread. Your code checks for the interruption - Thread.sleep and Object.wait will throw InterruptedException if the thread is interrupted before or during their execution; but you catch the interruption, and ignore it, so you won't act on it.
Instead of this:
while (condition) {
try {
Thread.sleep(...);
wait();
} catch (InterruptedException e) {
}
}
Put the interruption outside the loop:
try {
while (condition) {
Thread.sleep(...);
wait();
}
} catch (InterruptedException e) {
}
then the loop terminates if it is interrupted.
I want to have a thread which does some I/O work when it is interrupted by a main thread and then go back to sleep/wait until the interrupt is called back again.
So, I have come up with an implementation which seems to be not working. The code snippet is below.
Note - Here the flag is a public variable which can be accessed via the thread class which is in the main class
// in the main function this is how I am calling it
if(!flag) {
thread.interrupt()
}
//this is how my thread class is implemented
class IOworkthread extends Thread {
#Override
public void run() {
while(true) {
try {
flag = false;
Thread.sleep(1000);
} catch (InterruptedException e) {
flag = true;
try {
// doing my I/O work
} catch (Exception e1) {
// print the exception message
}
}
}
}
}
In the above snippet, the second try-catch block catches the InterruptedException. This means that both of the first and second try-catch block are catching the interrupt. But I had only called interrupt to happen during the first try-catch block.
Can you please help me with this?
EDIT
If you feel that there can be another solution for my objective, I will be happy to know about it :)
If it's important to respond fast to the flag you could try the following:
class IOworkthread extends Thread {//implements Runnable would be better here, but thats another story
#Override
public void run() {
while(true) {
try {
flag = false;
Thread.sleep(1000);
}
catch (InterruptedException e) {
flag = true;
}
//after the catch block the interrupted state of the thread should be reset and there should be no exceptions here
try {
// doing I/O work
}
catch (Exception e1) {
// print the exception message
// here of course other exceptions could appear but if there is no Thread.sleep() used here there should be no InterruptedException in this block
}
}
}
}
This should do different because in the catch block when the InterruptedException is caught, the interrupted flag of the thread is reset (at the end of the catch block).
It does sound like a producer/consumer construct. You seem to kind of have it the wrong way around, the IO should be driving the algorithm. Since you stay very abstract in what your code actually does, I'll need to stick to that.
So let's say your "distributed algorithm" works on data of type T; that means that it can be described as a Consumer<T> (the method name in this interface is accept(T value)). Since it can run concurrently, you want to create several instances of that; this is usually done using an ExecutorService. The Executors class provides a nice set of factory methods for creating one, let's use Executors.newFixedThreadPool(parallelism).
Your "IO" thread runs to create input for the algorithm, meaning it is a Supplier<T>. We can run it in an Executors.newSingleThreadExecutor().
We connect these two using a BlockingQueue<T>; this is a FIFO collection. The IO thread puts elements in, and the algorithm instances take out the next one that becomes available.
This makes the whole setup look something like this:
void run() {
int parallelism = 4; // or whatever
ExecutorService algorithmExecutor = Executors.newFixedThreadPool(parallelism);
ExecutorService ioExecutor = Executors.newSingleThreadExecutor();
// this queue will accept up to 4 elements
// this might need to be changed depending on performance of each
BlockingQueue<T> queue = new ArrayBlockingQueue<T>(parallelism);
ioExecutor.submit(new IoExecutor(queue));
// take element from queue
T nextElement = getNextElement(queue);
while (nextElement != null) {
algorithmExecutor.submit(() -> new AlgorithmInstance().accept(nextElement));
nextElement = getNextElement(queue);
if (nextElement == null) break;
}
// wait until algorithms have finished running and cleanup
algorithmExecutor.awaitTermination(Integer.MAX_VALUE, TimeUnit.YEARS);
algorithmExecutor.shutdown();
ioExecutor.shutdown(); // the io thread should have terminated by now already
}
T getNextElement(BlockingQueue<T> queue) {
int timeOut = 1; // adjust depending on your IO
T result = null;
while (true) {
try {
result = queue.poll(timeOut, TimeUnits.SECONDS);
} catch (TimeoutException e) {} // retry indefinetely, we will get a value eventually
}
return result;
}
Now this doesn't actually answer your question because you wanted to know how the IO thread can be notified when it can continue reading data.
This is achieved by the limit to the BlockingQueue<> which will not accept elements after this has been reached, meaning the IO thread can just keep reading and try to put in elements.
abstract class IoExecutor<T> {
private final BlockingQueue<T> queue;
public IoExecutor(BlockingQueue<T> q) { queue = q; }
public void run() {
while (hasMoreData()) {
T data = readData();
// this will block if the queue is full, so IO will pause
queue.put(data);
}
// put null into queue
queue.put(null);
}
protected boolean hasMoreData();
protected abstract T readData();
}
As a result during runtime you should at all time have 4 threads of the algorithm running, as well as (up to) 4 items in the queue waiting for one of the algorithm threads to finish and pick them up.
Might I ask here for a piece of advice.
I am creating several threads in the constructor of my class as I had a performance issue as I would like to add on more of series and flows. However those threads takes random time to initialize which means the code still execute and putting aside the order of my array list is now messed up, it is not fully loaded when the code keeps executing.
Series is a wrapper which add listeners and to simplify output a series of ArrayList that my frame needs to instantiate a chart in a panel.
what is the correct way to proceed here. I feel I do it all wrong.
new Thread(new Runnable() {
public void run() {
Flow flow = new Flow(idThread, 1);
flows.add(flow);
series.add(new Series(3000, ProcessingType.NONE, flow, controller));
series.add(new Series(5000, ProcessingType.FILTER, flow, controller));
}
}).start();
new Thread(new Runnable() {
public void run() {
Flow flow = new Flow(idThread, 2);
flows.add(flow);
series.add(new Series(4000, ProcessingType.NONE, flow, controller));
series.add(new Series(5000, ProcessingType.FILTER, flow, controller));
}
}).start();
Global.getInstance().mySeries(idThread, series);
trading = new Trading(idThread);
I try naively a
while (series.size()<10){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
However "logically" the main thread should sleep and allow time for the other ones to initialize?
Thanks
Don't extend Thread, implement Runnable. Don't start new threads from within a constructor unless you really like weird bugs. You can use various synchronization idioms such as https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html to "line the horses up at the gate before the race".
You can use a CyclicBarrier, where you can call await() method in main, until all you thread have reached this barrier your main thread will wait.
http://tutorials.jenkov.com/java-util-concurrent/cyclicbarrier.html
I am quite new to Threads in Java, I am using an API which is using thread internally and listening data from the counter party, I am putting this data in an queue for further processing. I have created another Thread which is continuously reading this queue for retrieving data and processing and to write the results into text file. I am using while(true) statement to run infinite loop in thread this cause a hundred per cent of CPU usage and if I use sleep(10) in it add up latency which keep on increasing with time as I am receiving about 20 data item in one second.
public void run() {
while(true) {
try { Thread.sleep(10); }
catch (InterruptedException e2) { // TODO Auto-generated catch block
e2.printStackTrace();
}
if (!(queue.isEmpt())) {
Tick quote=queue.take();
processTuple(quote);
}
} // end while(true)
} // end run()
Could anyone suggest me solution where I can reduce CPU usage without adding latency.
Check out ArrayBlockingQueue.
EDIT:
Example of how to use a queue based on your code:
LinkedBlockingQueue<Tick> queue;
public void run() {
while (true) {
// No need to check the queue. No need to sleep().
// take() will wait until there's anything available
Tick quote = queue.take();
processTuple(quote);
}
}
Ya. Use a BlockingQueue implementation instead of busy- wait. while(true) will keep scheduling the thread.
Use queue implementations instead of Threads. See this link to know more about queue implementations. You can use ArrayBlockingQueue.
You may change your code something like this:
BlockingQueue<Tick> queue = ..
public void run()
{
for (Tick quote; quote = queue.take(); )
{
if (quote == someSpecialObjectToIndicateStop)
break; // To stop this thread Or you may catch InterruptedException
processTuple(quote);
}
}
See BlockingQueue documentation here
Background (can skip to question below...)
Currently working with a lego Mindstorm robot and the icommand API (http://lejos.sourceforge.net/p_technologies/nxt/icommand/api/index.html).
Having some trouble with one of the motor control methods. The methods rotates the motor by a given angle:
Motor.A.rotateTo(target);
This function will not return until the motor has completed the movement. This is fine, but sometimes the motor fails to stop and will continue indefinitely thus stopping the program.
Question
Is there anyway I can make so the program waits for up n seconds for the method Motor.A.rotateTo(target); to return. And then if it has not returned in that time, then call the method again. (If that could be looped until it is successful that would be even better.)
Thanks for reading, any help would be much appreciated.
Regards,
Joe
edit: corrected from Motor.A.rotate(target); to Motor.A.rotateTo(target);
You can use ExecutorService or other threading solution to run rotate in a separate thread and wait for results. Here is a complete program that also retries given number of times:
public static void main(String[] args) throws TimeoutException {
final ExecutorService pool = Executors.newFixedThreadPool(10);
runWithRetry(pool, 5); //run here
}
public static void runWithRetry(final ExecutorService pool, final int retries) throws TimeoutException {
final Future<?> result = pool.submit(new Runnable() {
#Override
public void run() {
Motor.A.rotate(angle);
}
});
try {
result.get(1, TimeUnit.SECONDS); //wait here
} catch (InterruptedException e) {
throw new RuntimeException(e.getCause());
} catch (ExecutionException e) {
throw new RuntimeException(e.getCause());
} catch (TimeoutException e) {
if (retries > 1) {
runWithRetry(pool, retries - 1); //retry here
} else {
throw e;
}
}
}
What about Motor#rotate(long count, boolean returnNow) ? You can then call stop() if you want the motor to stop after a specific time.
Motor.A.rotate(150, true);
Thread.sleep(3000);
Motor.A.stop();
What about something along the lines of :
int desiredPosition = Motor.A.getTachoCount() + ANGLE_TO_TURN;
long timeout = System.currentTimeMillis + MAX_TIME_OUT;
Motor.A.forward();
while (timeout>System.currentTimeMillis && desiredPosition>Motor.A.getTachoCount()); //wait for the motor to reach the desired angle or the timeout to occur
Motor.A.stop();