How do i run a method after a delay? - java

I have a question regarding calling methods after a certain amount of delay.
I want to call a Java method exampleFunction() after a delay of about 10 seconds. I have looked for solutions online and have come across the ScheduledThreadPoolExecutor(). So I have used this, but the thing is, once the function runs after 10 seconds, it doesn't exit from the thread. Is there any way I can exit from the thread? Or can I run the ScheduledThreadPoolExecutor() on the current thread instead of creating a new thread?
class Test {
...
exampleFunction();
...
public void exampleFunction() {
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.schedule(new Runnable() {
public void run() {
...do something here...
}
}, 10, TimeUnit.SECONDS);
}
}
So is there any way I can exit this thread after exampleFunction runs after a delay of 10 seconds? Or can I have the ScheduledThreadPoolExecutor use the current thread instead of creating a new one?
Or is there another way I can approach this problem? I want to be able to run exampleFunction() after 10 seconds on the current thread, instead of creating a new thread.
Edit: I think it may not be a thread issue. I'm still trying to figure out the problem is. Thanks everyone for your suggestions and advice.
EDIT: Can I pass an argument to exampleFunction() and then use it inside public void run()?

I believe your problem may be that you are not shutting down the executor after your submit the job to it.
exec.schedule(...);
exec.shutdown();
The jobs that have been submitted will continue to run but you have to shutdown the service after you've submitted the last job to it.

Based on all the comments and confusion, any answer is just a guess.
What I think you want:
The UI thread to invoke exampleFunction
'exampleFunction` to schedule a task for 10 seconds later and return immediately
In 10 seconds time, to have the run method be invoked on the UI thread
In Swing, this is done by using SwingUtilities.invokeLater.
ExampleFunction would look like this:
public void exampleFunction() {
new Thread() {
public void run() {
TimeUnit.SECONDS.sleep(10); //Will need a try/catch
SwingUtilities.invokeLater(new Runnable() {
public void run() {
...do something here...
}
});
}
}.start();
}
Note: SwingUtilities.invokeAndWait could also be used.
Note 2: Although not usually advised, a simple Thread here is simpler than making a new Thread pool.

Thread.sleep can be used if merely wishing to making the current thread block. If you do use a pooled executor, make sure to use it as a pooled executor - not one per (new) thread. To "exit" from a thread, just let execution run out of run. If using Swing, use the EDT.

Related

Android - how to prevent UI lag via Handler?

I've got a Handler that runs a runnable task every 2 seconds. It runs a fairly intensive task (executes a shell command). Every time the I run handler.postDelayed(update, 2000); the user interface lags (for 2 seconds). How do I stop this lag?
I know there's lag because I have a dynamic interface, so I can move around a view and when the handler is run the interface becomes unresponsive for the 2 seconds.
Is there a way to go around this?
You are doing this work on the main UI thread, which is not acceptable for your user to have a good experience, as you have already identified.
You can instead create a new background thread for your handler to run any posted runnables on, which will take the least amount of code change:
mHandlerThread = new HandlerThread("YourHandlerThread");
mHandlerThread.start();
handler = new Handler(mHandlerThread.getLooper());
// Now post your runnable, as before
handler.postDelayed(update, 2000);
Just keep in mind that you cannot touch any UI elements from this thread, as that is not allowed by Android.
when the handler is run the interface becomes unresponsive for the 2 seconds
That means that you are doing two seconds' worth of work on the main application thread. Doing 2 milliseconds' worth of work is more appropriate.
The Runnable that is passed to postDelayed() has its run() method called on the main application thread. If this work will take more than a millisecond or two, you should be using something other than Handler and postDelayed() for your every-two-seconds work, such as a ScheduledExecutorService.
Handler is a way to run code on the UI Thread in Android.
If you don't need your code run on the UI Thread, you may want to consider just making your own Thread or using an Executor.
I've fixed it. Thanks to everyone notifying me that the Handler runs on the UI thread...
I've now run a separate thread to update the variable used in the handler task:
double p = 0;
public void z(){
Thread t = new Thread(){
#Override
public void run(){
p = a.b();
}
};
t.start();
}
Runnable y = new Runnable() {
#Override
public void run() {
z();
c.setText(String.valueOf(p));
d.setProgress(Float.valueOf(String.valueOf(p / 100)));
handler.postDelayed(this, 2000);
}
};`

stop an infinite loop within a thread

Thread d = new Thread(new Runnable() {
#Override
public void run() {
while(true);
}
});
d.start();
How can I quit the infinite loop, without changing the code inside the method public void run(),
and without using d.stop(); (deprecated method).
P.S: I'd prefer publishing the whole exercise details I need to do. That's kinda the thing I need to dill with. They gave me a function which sometimes goes inside infinite loop, and I can't change that method.
How can I quit the infinite loop, without changing the code inside the method public void run(), and without using d.stop(); (deprecated method).
I assume this is some sort of academic or interview question. If you can't change the thread code then you can't add an interrupt or volatile boolean check. And you can't call .stop() (which is btw deprecated and never a good idea).
The only thing I can think of is to set the thread be a daemon thread.
Thread d = new Thread(new Runnable() { ... });
...
d.setDaemon(true);
d.start();
It needs to be set daemon before it is started. This is a hack but maybe within the framework of the question. This won't kill the thread immediately but if the last non-daemon thread exits then the thread will be killed by the JVM.
Of course you can also remove the .start() line but that seems outside the realm of the question. System.exit(0); would also bring down the JVM as #MattBall pointed out but that also seems like cheating.
Outside of killing the JVM running the thread, I don't see how you can quit the loop.
A better method would at minimum check for thread interruption:
Thread d = new Thread(new Runnable() {
#Override
public void run() {
while(!Thread.currentThread().isInterrupted());
};
d.start();
d.interrupt();
You can't. The only way to stop a thread asynchronously is the stop() method. But without that, you can't.
Without .stop() you need to change the code in the thread itself. see here here for some ideas.
Always avoid while(true). Try while(running). That condition should determine the life of the loop. Then when you set running = false, the life of the loop ends and subsequently the thread.

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.

How to give delay in java progrramming?

I want to draw number of rectangles one after another using a specific time .
I use thread.sleep() method but it is directly stop working of thread and not resume.
Use Thread.sleep(long millis) instead, on the worker thread.
Specify number of milliseconds in sleep:
Thread.sleep(2000); // two seconds
Note that you need to handle InterruptedException.
You need to put the sleep in another thread. If you put the sleep in your GUI-thread, the GUI will freeze.
edit: My bad, will leave this here as a side note comment instead.
You could use Timer and TimeTask classes.
See this example.
Look at the java executors. These can run for a fixed time. Inside each executor unit you can then draw a rectangle. (on the EDT) This API document has a useful example at the top
You should instantiate each draw in a separate thread. Create the separate thread for every loop of the sleep.
This way, you would separate the thread for looping, and the thread for drawing. Thus, removes the freezing.
public class RunTest implements Runnable{
#Override
public void run() {
// codes for drawing
}
}
And in your main:
try {
while (true) {
Thread t = new Thread(new RunTest());
t.start();
}
} catch (InterruptedException iex) {}
This will create an infinite number of Threads for you drawing. Just modify this loop.
See here for threads.

java background task

I was wondering which would be the most efficient approach to implement some kind of background task in java (I guess that would be some kind of nonblocking Threads). To be more precise - I have some java code and then at some point I need to execute a long running operation. What I would like to do is to execute that operation in the background so that the rest of the program can continue executing and when that task is completed just update some specific object which. This change would be then detected by other components.
You want to make a new thread; depending on how long the method needs to be, you can make it inline:
// some code
new Thread(new Runnable() {
#Override public void run() {
// do stuff in this thread
}
}).start();
Or just make a new class:
public class MyWorker extends Thread {
public void run() {
// do stuff in this thread
}
}
// some code
new MyWorker().start();
You should use Thread Pools,
http://java.sun.com/docs/books/tutorial/essential/concurrency/pools.html
Naïve idea : you might be able to create Thread, give it a low priority, and do a loop of :
doing a little bit of work
using yield or sleep to let other threads work in parrallel
That would depend on what you actually want to do in your thread
Yes, you're going to want to spin the operation off on to it's own thread. Adding new threads can be a little dangerous if you aren't careful and aware of what that means and how resources will interact. Here is a good introduction to threads to help you get started.
Make a thread. Mark this thread as Daemon. The JVM exits when the only thread running are all daemon threads.

Categories

Resources