More efficient way for pausing loop wanted - java

Is it possible to rewrite this code for better working with processor?
I have a class, which does some tasks with fixed periodicy in a separate thread. Sometimes this process can be paused and resumed. Currently I am using a flag for pausing, it works fine, but loop in this way still loads processor when process is paused. Is it possible to fix this?
private boolean mIsCanceled = false;
private boolean mIsPaused = true; // TODO more efficient for processor way of pausing is required
private final Thread mTimerThread = new Thread(new Runnable() {
#Override
public void run() {
while(!mIsCanceled){
try {
Thread.sleep(UPDATE_PERIOD);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!mIsPaused){
doStep();
}
}
}
});
public MyClass(){
mTimerThread.start();
}
private void pause(){
mIsPaused = true;
}
private void resume(){
mIsPaused = false;
}
private void doStep(){
// Some code
}
Please just provide alternative implementation of my code.
P.S. The environment is Android OS 2.2+

The tools available are:
wait/notify - we are all trying to get away from this archaic system.
Semaphores - once your thread has grabbed it you hold it until release so grabbing it again does not block. This means you cannot pause from within your own thread.
CyclicBarrier - Must be created anew each time it is used.
ReadWriteLock - My favorite. You can have as many threads pausing you as you like and you will only resume when all of them have called resume. You can even pause yourself if you wish.
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* PauseableThread is a Thread with pause/resume and cancel methods.
*
* The meat of the process must implement `step`.
*
* You can either extend this and implement `step` or use the factory.
*
* Note that I cannot extend Thread because my resume will clash with Thread's deprecated one.
*
* Usage: Either write a `Stepper` and run it in a `PausableThread` or extend `PausableThread` and call `blockIfPaused()` at appropriate points.
*/
public abstract class PauseableThread implements Runnable {
// The lock.
// We'll hold a read lock on it to pause the thread.
// The thread will momentarily grab a write lock on it to pause.
// This way you can have multiple pausers using normal locks.
private final ReadWriteLock pause = new ReentrantReadWriteLock();
// Flag to cancel the wholeprocess.
private volatile boolean cancelled = false;
// The exception that caused it to finish.
private Exception thrown = null;
#Override
// The core run mechanism.
public void run() {
try {
while (!cancelled) {
// Block here if we're paused.
blockIfPaused();
// Do my work.
step();
}
} catch (Exception ex) {
// Just fall out when exception is thrown.
thrown = ex;
}
}
// Block if pause has been called without a matching resume.
private void blockIfPaused() throws InterruptedException {
try {
// Grab a write lock. Will block if a read lock has been taken.
pause.writeLock().lockInterruptibly();
} finally {
// Release the lock immediately to avoid blocking when pause is called.
pause.writeLock().unlock();
}
}
// Pause the work. NB: MUST be balanced by a resume.
public void pause() {
// We can wait for a lock here.
pause.readLock().lock();
}
// Resume the work. NB: MUST be balanced by a pause.
public void resume() {
// Release the lock.
pause.readLock().unlock();
}
// Stop.
public void cancel() {
// Stop everything.
cancelled = true;
}
// start - like a thread.
public void start() {
// Wrap it in a thread.
new Thread(this).start();
}
// Get the exceptuion that was thrown to stop the thread or null if the thread was cancelled.
public Exception getThrown() {
return thrown;
}
// Create this method to do stuff.
// Calls to this method will stop when pause is called.
// Any thrown exception stops the whole process.
public abstract void step() throws Exception;
// Factory to wrap a Stepper in a PauseableThread
public static PauseableThread make(Stepper stepper) {
StepperThread pauseableStepper = new StepperThread(stepper);
// That's the thread they can pause/resume.
return pauseableStepper;
}
// One of these must be used.
public interface Stepper {
// A Stepper has a step method.
// Any exception thrown causes the enclosing thread to stop.
public void step() throws Exception;
}
// Holder for a Stepper.
private static class StepperThread extends PauseableThread {
private final Stepper stepper;
StepperThread(Stepper stepper) {
this.stepper = stepper;
}
#Override
public void step() throws Exception {
stepper.step();
}
}
// My test counter.
static int n = 0;
// Test/demo.
public static void main(String[] args) throws InterruptedException {
try {
// Simple stepper that just increments n.
Stepper s = new Stepper() {
#Override
public void step() throws Exception {
n += 1;
Thread.sleep(10);
}
};
PauseableThread t = PauseableThread.make(s);
// Start it up.
t.start();
Thread.sleep(1000);
t.pause();
System.out.println("Paused: " + n);
Thread.sleep(1000);
System.out.println("Resuminng: " + n);
t.resume();
Thread.sleep(1000);
t.cancel();
} catch (Exception e) {
}
}
}
Edit: Code modified to be of more general use.

Your best options are to either use wait()/notify() or to simply switch to ScheduledExecutorService
Proper wait()/notify() usage can be tricky. I highly recommend "Java Concurrency in Practice" to learn more about threading.

I believe the best way here would be to use Thread.wait for the waiting thread instead of sleeping, and use Thread.notify in the thread you are waiting for.
More info here:
http://www.javamex.com/tutorials/synchronization_wait_notify.shtml

You can improve efficiency drastic by using a monitor instead of sleeping the thread. You just make blocks in your code with a keyword synchronized. And an final Object that's acts the monitor. Look uP more in the API on monitors.

Related

Multithreading: 2 tasks

I have folowwing situation:
I want to run 2 threads:
Thread A: a void function which runs 1 time
Thread B: a method which never ends
I want to run thread A, than Thread B, than Thread A again, B again,...
But the Thread B blocks Thread A because it's function never ends.
Can someone give me an example to solve this scheduling problem in Java?
What I want to achieve is
Let thread A run for 1 minute
Stop thread A
Let thread B run for 5 seconds
Stop thread B
Let thread A run for 1 minute
Stop thread A
...
I wrote this PauseableThread a while ago - it should do what you are looking for. It uses Locks to control pausing of a thread.
Instead of writing a Runnable you write a Stepper. This will call your Stepper.step() continuously so long as it has not been told to pause.
/**
* PauseableThread is a Thread with pause/resume and cancel methods.
*
* The meat of the process must implement `step`.
*
* You can either extend this and implement `step` or use the factory.
*
* I cannot extend Thread because my resume will clash.
*
*/
public abstract class PauseableThread implements Runnable {
// The lock.
private final ReadWriteLock pause = new ReentrantReadWriteLock();
private final Lock readLock = pause.readLock();
private final Lock writeLock = pause.writeLock();
// Flag to cancel the wholeprocess.
private volatile boolean cancelled = false;
// The exception that cause it to finish.
private Exception thrown = null;
// The thread that is me.
private Thread me = null;
#Override
// The core run mechanism.
public void run() {
// Track my current thread.
me = Thread.currentThread();
try {
while (!finished()) {
// Block here if we're paused.
blockIfPaused();
// Don't do any more work if we've been asked to stop.
if (!finished()) {
// Do my work.
step();
}
}
} catch (Exception ex) {
// Just fall out when exception is thrown.
thrown = ex;
}
}
// Have we finished yet?
private boolean finished() {
return cancelled || me.isInterrupted();
}
// Block if pause has been called without a matching resume.
private void blockIfPaused() throws InterruptedException {
try {
// Grab a write lock. Will block if a read lock has been taken - i.e. we've been paused.
writeLock.lockInterruptibly();
} finally {
// Release the lock immediately to avoid blocking when pause is called.
writeLock.unlock();
}
}
// Pause the work. NB: MUST be balanced by a resume.
public void pause() {
// We can wait for a lock here.
readLock.lock();
}
// Resume the work. NB: MUST be balanced by a pause.
public void resume() {
// Release the lock.
readLock.unlock();
}
// Stop.
public void cancel() {
// Stop everything.
cancelled = true;
}
// Stop immediately (if param is true).
public void cancel(boolean interrupt) {
if (interrupt) {
// Interrupt me.
me.interrupt();
} else {
// Or cancel me.
cancel();
}
}
// Wait for completion.
public void await() throws InterruptedException {
// Wait 'till we've finished. NB: Will wait forever if you haven't instigated a cancel of some kind.
while (me.isAlive()) {
Thread.sleep(0);
}
}
// Start - like a thread.
public void start() {
// Wrap me in a thread and fire the sucker up!
new Thread(this).start();
}
// Get the exception that was thrown to stop the thread or null if the thread was cancelled.
public Exception getThrown() {
return thrown;
}
// Expose my Thread.
public Thread getThread() {
return me;
}
// Create this method to do stuff.
// Calls to this method will stop when pause is called.
// Any thrown exception stops the whole process.
public abstract void step() throws Exception;
// Factory to wrap a Stepper in a PauseableThread
public static PauseableThread make(Stepper stepper) {
StepperThread pauseableStepper = new StepperThread(stepper);
// That's the thread they can pause/resume.
return pauseableStepper;
}
// One of these must be used.
public interface Stepper {
// A Stepper has a step method.
// Any exception thrown causes the enclosing thread to stop.
public void step() throws Exception;
}
// Holder for a Stepper.
private static class StepperThread extends PauseableThread {
// The actual stepper I am proxying.
private final Stepper stepper;
StepperThread(Stepper stepper) {
this.stepper = stepper;
}
#Override
public void step() throws Exception {
stepper.step();
}
}
// !!!! Testing only below !!!!
// My test counter.
static int n = 0;
// Test/demo.
public static void main(String[] args) throws InterruptedException {
try {
// Simple stepper that just increments n.
Stepper s = () -> {
n += 1;
Thread.sleep(1);
};
PauseableThread pt = PauseableThread.make(s);
// Start it up.
pt.start();
Thread.sleep(1000);
pt.pause();
System.out.println("Paused: " + n);
Thread.sleep(1000);
System.out.println("Resuminng: " + n);
pt.resume();
Thread.sleep(1000);
pt.cancel();
pt.await();
System.out.println("Finished: " + n);
// Start again to test agressive cancelling.
n = 0;
pt = PauseableThread.make(s);
// Start it up.
pt.start();
Thread.sleep(1000);
pt.pause();
System.out.println("Paused: " + n);
Thread.sleep(1000);
System.out.println("Resuminng: " + n);
pt.resume();
Thread.sleep(1000);
// Cancel aggressively.
pt.cancel(true);
System.out.println("Finished: " + n);
System.out.println("thrown: " + pt.getThrown());
} catch (InterruptedException e) {
}
}
}

Java threaded for loop with pause and resume

let say i have a for loop of 1000 and it do some stuff. I can inside a pause function with a button 'pause' and unpause with a button 'resume'.
Question do i need to implement a thread for such a case?
for (int i = 0; i < 1000; i++) {
// Do stuff
pause();
}
If I understand you correctly, the answer is No, you don't need to implement an additional thread. If you follow the usual pattern for GUI programs, this thread will be running in a thread different from the main GUI thread anyway, and that is sufficient.
You will need to check in each iteration of the for loop that the user paused the system and wait for the resume. This can be done with a simple notify signal pattern. For instance
I think you need a thread because this loop you're showing has to be run in a worker thread, while the button and the code processing the button press event has to be run in the GUI thread. So from the GUI thread you want to pause your worker thread.
You may use boolean flag:
public volatile boolean paused = false;
public final int littleTime = 100; //ms
for (int i = 0; i < 1000; ++i) {
// Do stuff
pause();
}
public void pause() {
paused = true;
while (paused)
try {
Thread.sleep(littleTime);
} catch (InterruptedException e) {}
}
public void resume() {
paused = false;
}
Have a boolean to state if it is Paused
volatile boolean isPause = false;
for (int i = 0; i < 1000; i++) {
// Do stuff if not passed
if(!isPause)
doStuff();
}
Note : Set the isPause flag to true when you hit Pause button. Reset the isPause flag to false when you hit Resume button. I have also marked boolean as volatile so that the variable is always read from main memory (no cache) since both read and write are atomic in this case
This implements a pauseable thread. See the comments at the top on how to use it. See examples of usage in the main method.
/**
* PauseableThread is a Thread with pause/resume and cancel methods.
*
* The meat of the process must implement `step`.
*
* You can either extend this and implement `step` or use the factory.
*
* I cannot extend Thread because my resume will clash.
*
*/
public abstract class PauseableThread implements Runnable {
// The lock.
private final ReadWriteLock pause = new ReentrantReadWriteLock();
private final Lock readLock = pause.readLock();
private final Lock writeLock = pause.writeLock();
// Flag to cancel the wholeprocess.
private volatile boolean cancelled = false;
// The exception that cause it to finish.
private Exception thrown = null;
// The thread that is me.
private Thread me = null;
#Override
// The core run mechanism.
public void run() {
// Track my current thread.
me = Thread.currentThread();
try {
while (!finished()) {
// Block here if we're paused.
blockIfPaused();
// Don't do any more work if we've been asked to stop.
if (!finished()) {
// Do my work.
step();
}
}
} catch (Exception ex) {
// Just fall out when exception is thrown.
thrown = ex;
}
}
// Have we finished yet?
private boolean finished() {
return cancelled || !me.isInterrupted();
}
// Block if pause has been called without a matching resume.
private void blockIfPaused() throws InterruptedException {
try {
// Grab a write lock. Will block if a read lock has been taken.
writeLock.lockInterruptibly();
} finally {
// Release the lock immediately to avoid blocking when pause is called.
writeLock.unlock();
}
}
// Pause the work. NB: MUST be balanced by a resume.
public void pause() {
// We can wait for a lock here.
readLock.lock();
}
// Resume the work. NB: MUST be balanced by a pause.
public void resume() {
// Release the lock.
readLock.unlock();
}
// Stop.
public void cancel() {
// Stop everything.
cancelled = true;
}
// Stop immediately (if param is true).
public void cancel(boolean interrupt) {
if (interrupt) {
// Interrupt me.
me.interrupt();
} else {
// Or cancel me.
cancel();
}
}
// Wait for completion.
public void await() throws InterruptedException {
// Wait 'till we've finished. NB: Will wait forever if you haven't instigated a cancel of some kind.
while (me.isAlive()) {
Thread.sleep(0);
}
}
// Start - like a thread.
public void start() {
// Wrap me in a thread and fire the sucker up!
new Thread(this).start();
}
// Get the exception that was thrown to stop the thread or null if the thread was cancelled.
public Exception getThrown() {
return thrown;
}
// Expose my Thread.
public Thread getThread() {
return me;
}
// Create this method to do stuff.
// Calls to this method will stop when pause is called.
// Any thrown exception stops the whole process.
public abstract void step() throws Exception;
// Factory to wrap a Stepper in a PauseableThread
public static PauseableThread make(Stepper stepper) {
StepperThread pauseableStepper = new StepperThread(stepper);
// That's the thread they can pause/resume.
return pauseableStepper;
}
// One of these must be used.
public interface Stepper {
// A Stepper has a step method.
// Any exception thrown causes the enclosing thread to stop.
public void step() throws Exception;
}
// Holder for a Stepper.
private static class StepperThread extends PauseableThread {
// The actual stepper I am proxying.
private final Stepper stepper;
StepperThread(Stepper stepper) {
this.stepper = stepper;
}
#Override
public void step() throws Exception {
stepper.step();
}
}
// !!!! Testing only below !!!!
// My test counter.
static int n = 0;
// Test/demo.
public static void main(String[] args) throws InterruptedException {
try {
// Simple stepper that just increments n.
Stepper s = new Stepper() {
#Override
public void step() throws Exception {
n += 1;
Thread.sleep(1);
}
};
PauseableThread pt = PauseableThread.make(s);
// Start it up.
pt.start();
Thread.sleep(1000);
pt.pause();
System.out.println("Paused: " + n);
Thread.sleep(1000);
System.out.println("Resuminng: " + n);
pt.resume();
Thread.sleep(1000);
pt.cancel();
System.out.println("Finished: " + n);
// Start again to test agressive cancelling.
pt.await();
n = 0;
pt = PauseableThread.make(s);
// Start it up.
pt.start();
Thread.sleep(1000);
pt.pause();
System.out.println("Paused: " + n);
Thread.sleep(1000);
System.out.println("Resuminng: " + n);
pt.resume();
Thread.sleep(1000);
// Cancel aggressively.
pt.cancel(true);
System.out.println("Finished: " + n);
System.out.println("thrown: " + pt.getThrown());
} catch (InterruptedException e) {
}
}
}

Java Multithreading doesn't seem to be correctly working

I have a class which processes something. I'm trying to run a number of instances of this class in parallel.
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping. So I'd like to know if I'm doing something wrong?
This is the structure of the class:
public class TaskRunner implements Runnable {
private boolean isRunning = false;
public void run() {
while(true) {
while (! running) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
process();
}
}
public void go() {
isRunning = true;
}
public void stop() {
isRunning = false;
}
private void process() {
//Do some number crunching and processing here
}
}
Here's how these are being run / managed:
public class TaskManager {
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager() {
for (int i = 0; i < 10; i++) {
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
}
public void startAll() {
for (TaskRunner r : runners) {
r.go();
}
}
}
Indeed, you are not "doing it right." If you want to create a multi-threaded Java application, the place to start is with the java.util.concurrent package.
It appears from your code that you want to run ten tasks in parallel. I assume that after "number crunching and processing," you'll want to aggregate the results and do something with them in the main thread. For this, the invokeAll() method of ExecutorService works well.
First, implement Callable to do the work you show in your process() method.
final class YourTask implements Callable<YourResults> {
private final YourInput input;
YourTask(YourInput input) {
this.input = input;
}
#Override
public YourResults call()
throws Exception
{
/* Do some number crunching and processing here. */
return new YourResults(...);
}
}
Then create your tasks and run them. This would take the place of your main() method:
Collection<Callable<YourResults>> tasks = new List<>(inputs.size());
for (YourInput i : inputs)
tasks.add(new YourTask(i));
ExecutorService workers = Executors.newFixedThreadPool(10);
/* The next call blocks while the worker threads complete all tasks. */
List<Future<YourResult>> results = workers.invokeAll(tasks);
workers.shutdown();
for (Future<YourResult> f : results) {
YourResult r = f.get();
/* Do whatever it is you do with the results. */
...
}
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
So my first comment is that you should make isRunning be volatile since it is being shared between threads. If the threads are not starting when it goes to true (or seem to be delayed in starting) then I suspect that's your problem. volatile provides memory synchronization between the threads so the thread that calls go() and makes a change to isRunning will be seen immediately by the thread waiting for the change.
Instead of spinning like this, I would use wait/notify:
// this synchronizes on the instance of `TaskRunner`
synchronized (this) {
// always do your wait in a while loop to protect against spurious wakeups
while (!isRunning && !Thread.currentThread().isInterrupted()) {
try {
// wait until the notify is called on this object
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
Then in the go() method you should do the following. stop() would be similar.
public void go() {
synchronized (this) {
isRunning = true;
this.notifyAll();
}
}
Notice that you should handle thread interrupts carefully. Test for isInterrupted() in the while running loop and re-interrupt a thread when InterruptedException is thrown is always a good pattern.
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping.
So although the threads are mostly sleeping, they are still each looping 1000 times a second because of your Thread.sleep(1). If you increased the time sleeping (after making isRunning be volatile) they would loop less but the right mechanism is to use the wait/notify to signal the thread.
Awful solution, terrible. first I highly recommend you start reading some tutorial like [this]
Second, if threads should wait for a signal to go for some job, so why just don't you wait them!!!!!, something like this
import java.util.ArrayList;
public class TaskManager
{
//////////////////////
public volatile static Signal wait=new Signal();
//////////////////////
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager()
{
for (int i = 0; i < 10; i++)
{
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
try {
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
pauseAll();
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
haltAll();System.out.println("DONE!");
}catch(Exception ex){}
}
public void startAll()
{
synchronized(wait){
wait.setRun(true);;
wait.notifyAll();
}
}
public void pauseAll(){
wait.setRun(false);
}
public void haltAll(){
for(TaskRunner tx:runners){tx.halt();}
}
public static void main(String[] args) {
new TaskManager();
}
}
class TaskRunner implements Runnable
{
private Thread thisThread;
private volatile boolean run=true;
public void run()
{
thisThread=Thread.currentThread();
while(run){
if(!TaskManager.wait.isRun()){
synchronized(TaskManager.wait)
{
if(!TaskManager.wait.isRun()){
System.out.println("Wait!...");
try
{
TaskManager.wait.wait();
}
catch (Exception e)
{
e.printStackTrace();
break;
}
}
}}
process();
}
}
private double r=Math.random();
private void process(){System.out.println(r);try {
Thread.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}}
public void halt(){run=false;thisThread.interrupt();}
}
class Signal{
private boolean run=false;
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
in above sample, all runners works till the Signal run boolean is true, and simple TaskManager class set tit as false for every time it needs to pause the threads. and about the halt, it just set the shutdown(run) flag to false, and also interrupt the thread because of if thread is in wait state.
I hope I could prove your solution is like dream-on story, and also could explained enough about my solution.
have a good parallel application :)

Can a thread only execute certain methods in Java?

I'm working on making an interface for a robot. My Robot class has methods that include movement, stopping movement and reading sensor data. If at all possible, I'd like to have certain methods run under a given thread and certain other methods run under another. I'd like to be able to send the command to move to the robot object, have the thread executing it sleep duration milliseconds and then stop movement, but I'd like the stop() method able to be called and interrupt the thread executing the movement. Any help is greatly appreciated.
public class robotTest
{
public static void main(String[] args) throws InterruptedException
{
Robot robot = new Robot(); //Instantiate new Robot object
robot.forward(255, 100, Robot.DIRECTION_RIGHT, 10); //Last argument representing duration
Thread.sleep(5000); //Wait 5 seconds
robot.stop(); //Stop movement prematurely
}
}
I would suggest instantiating your Robot class with an ExecutorService that you can use for moving asynchronusly. Submit the movement request to your service and use the Future returned to 'stop' the move request.
class Robot{
final ExecutorService movingService = Executors.newSingleThreadExecutor();
private volatile Future<?> request; //you can use a Deque or a List for multiple requests
public void forward(int... args){
request = movingService.submit(new Runnable(){
public void run(){
Robot.this.move(args);
}
});
}
public void stop(){
request.cancel(true);
}
}
If I'm understanding you correctly then yes, you can call methods on an object from any given thread. However, for this to work in a bug free fashion the robot class needs to be thread safe.
Make sure all your calls to Robot come from a thread (a class extending Thread that you create) with permissions to make the calls. Add this method to your call.
Note: this code is far from perfect. But it may give you some ideas you can use in your application.
public void stop() throws NoPermissionException {
checkStopPermission(); // throws NoPermissionException
// rest of stop here as normal
}
/**
* Alternatively you could return a boolean for has permission and then throw the NoPermissionException up there.
*/
private void checkStopPermission() throws NoPermissionException() {
try {
Thread t = Thread.currentThread();
RobotRunnableThread rrt = (RobotRunnableThread)t; // may throw cast exception
if(!rrt.hasPermission(RobotRunnableThread.STOP_PERMISSION)) { // assume Permission enum in RobotRunnableThread
throw new NoPermissionExeception();
}
} catch(Exception e) { // perhaps catch the individual exception(s)?
throw new NoPermissionException();
}
}
You have to start a new background thread when you instantiate a Robot that would handle movement. The thread would sit there, waiting for a signal from forward or stop and do the appropriate thing.
You will have to synchronize the threads using either semaphores, wait handles, or other inter thread communication elements.
The least robust solution that wastes the most CPU (this is pseudo code since I have not used Java in a while, might be intermixed with .NET APIs):
public class Robot implements IRunnable {
public Robot() {
new Thread(this).Start();
}
private int direction = 0;
private int duration = 0;
private bool go = false;
public void Run() {
DateTime moveStartedAt;
bool moving = false;
while(true) {
if(go) {
if(moving) {
// we are already moving
if((DateTime.Now - moveStartedAt).Seconds >= duration) {
moving = false;
}
} else {
moveStartedAt = DateTime.Now;
moving = true;
}
} else {
moving = false;
}
}
}
public void forward(int direction, int duration) {
this.direction = direction;
this.duration = duration;
this.go = true;
}
public void stop() {
this.go = false;
}
}
(the above code should be modified to be Java for better answer)
What is wrong with this code:
The Run() method consumes one whole Core (it has no sleeps)
Calling stop() and then forward() right away can result in a race condition (the Run() has not seen the stop yet, but you already gave it another forward)
There is no way for Run() to exit
You can call forward() to redirect the move that is already in progress
Others?

How do I call some blocking method with a timeout in Java?

Is there a standard nice way to call a blocking method with a timeout in Java? I want to be able to do:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
if that makes sense.
Thanks.
You could use an Executor:
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(true); // may or may not desire this
}
If the future.get doesn't return in 5 seconds, it throws a TimeoutException. The timeout can be configured in seconds, minutes, milliseconds or any unit available as a constant in TimeUnit.
See the JavaDoc for more detail.
You could wrap the call in a FutureTask and use the timeout version of get().
See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
See also Guava's TimeLimiter which uses an Executor behind the scenes.
It's really great that people try to implement this in so many ways. But the truth is, there is NO way.
Most developers would try to put the blocking call in a different thread and have a future or some timer. BUT there is no way in Java to stop a thread externally, let alone a few very specific cases like the Thread.sleep() and Lock.lockInterruptibly() methods that explicitly handle thread interruption.
So really you have only 3 generic options:
Put your blocking call on a new thread and if the time expires you just move on, leaving that thread hanging. In that case you should make sure the thread is set to be a Daemon thread. This way the thread will not stop your application from terminating.
Use non blocking Java APIs. So for network for example, use NIO2 and use the non blocking methods. For reading from the console use Scanner.hasNext() before blocking etc.
If your blocking call is not an IO, but your logic, then you can repeatedly check for Thread.isInterrupted() to check if it was interrupted externally, and have another thread call thread.interrupt() on the blocking thread
This course about concurrency https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
really walks through those fundamentals if you really want to understand how it works in Java. It actually talks about those specific limitations and scenarios, and how to go about them in one of the lectures.
I personally try to program without using blocking calls as much as possible. There are toolkits like Vert.x for example that make it really easy and performant to do IO and no IO operations asynchronously and in a non blocking way.
I hope it helps
There is also an AspectJ solution for that with jcabi-aspects library.
#Timeable(limit = 30, unit = TimeUnit.MINUTES)
public Soup cookSoup() {
// Cook soup, but for no more than 30 minutes (throw and exception if it takes any longer
}
It can't get more succinct, but you have to depend on AspectJ and introduce it in your build lifecycle, of course.
There is an article explaining it further: Limit Java Method Execution Time
I'm giving you here the complete code. In place of the method I'm calling, you can use your method:
public class NewTimeout {
public String simpleMethod() {
return "simple method";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException {
Thread.sleep(1100);
return new NewTimeout().simpleMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
} catch (TimeoutException ex) {
System.out.println("Timeout............Timeout...........");
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
executor.shutdown(); // may or may not desire this
}
}
}
Thread thread = new Thread(new Runnable() {
public void run() {
something.blockingMethod();
}
});
thread.start();
thread.join(2000);
if (thread.isAlive()) {
thread.stop();
}
Note, that stop is deprecated, better alternative is to set some volatile boolean flag, inside blockingMethod() check it and exit, like this:
import org.junit.*;
import java.util.*;
import junit.framework.TestCase;
public class ThreadTest extends TestCase {
static class Something implements Runnable {
private volatile boolean stopRequested;
private final int steps;
private final long waitPerStep;
public Something(int steps, long waitPerStep) {
this.steps = steps;
this.waitPerStep = waitPerStep;
}
#Override
public void run() {
blockingMethod();
}
public void blockingMethod() {
try {
for (int i = 0; i < steps && !stopRequested; i++) {
doALittleBit();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void doALittleBit() throws InterruptedException {
Thread.sleep(waitPerStep);
}
public void setStopRequested(boolean stopRequested) {
this.stopRequested = stopRequested;
}
}
#Test
public void test() throws InterruptedException {
final Something somethingRunnable = new Something(5, 1000);
Thread thread = new Thread(somethingRunnable);
thread.start();
thread.join(2000);
if (thread.isAlive()) {
somethingRunnable.setStopRequested(true);
thread.join(2000);
assertFalse(thread.isAlive());
} else {
fail("Exptected to be alive (5 * 1000 > 2000)");
}
}
}
You need a circuit breaker implementation like the one present in the failsafe project on GitHub.
Try this. More simple solution. Guarantees that if block didn't execute within the time limit. the process will terminate and throws an exception.
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* #return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* #param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
example :
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
#Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}
In special case of a blocking queue:
Generic java.util.concurrent.SynchronousQueue has a poll method with timeout parameter.
Assume blockingMethod just sleep for some millis:
public void blockingMethod(Object input) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My solution is to use wait() and synchronized like this:
public void blockingMethod(final Object input, long millis) {
final Object lock = new Object();
new Thread(new Runnable() {
#Override
public void run() {
blockingMethod(input);
synchronized (lock) {
lock.notify();
}
}
}).start();
synchronized (lock) {
try {
// Wait for specific millis and release the lock.
// If blockingMethod is done during waiting time, it will wake
// me up and give me the lock, and I will finish directly.
// Otherwise, when the waiting time is over and the
// blockingMethod is still
// running, I will reacquire the lock and finish.
lock.wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So u can replace
something.blockingMethod(input)
to
something.blockingMethod(input, 2000)
Hope it helps.

Categories