How to reinitialise the very same thread in android? - java

I'm using GCM to receive message from google server. when the message has received at device ; it starts a 1-minute thread, and if no other message has come until 1min it will show the analog clock on screen. but if before 1 minute the message has come: here's the problem how can reinitialise the thread from zero to measure again 1min???
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
}
handler.post(new Runnable() {
#Override
public void run() {
analogClock.setVisibility(View.VISIBLE);
lblMessage.setText("");
}
});
}
});
t.start ();
// Schedule task to terminate thread in 1 minute
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.schedule (
new Runnable(){
#Override
public void run (){
t.interrupt();
}
} , 1, TimeUnit.MINUTES);
}

Simplest solution seems to be to keep a rest boolean in the thread - when you scheduled runnable executes you can either terminate the thread or reschedule this runnable for a new minute in the future.
You can't exactly reuse a thread in Java but you can plan NOT to terminate your thread unless it is appropriate.

In Java you really can't reuse threads (see here). Just create another one.
To cancel previous task you can cancel the ScheduledFuture using cancel(boolean):
ScheduledFuture<?> future = exec.schedule (
new Runnable(){
#Override
public void run (){
t.interrupt();
}
} , 1, TimeUnit.MINUTES);
}
...
future.cancel(true); // Or false, I don't know your exact requirements here
Anyway in your case and in Android you're better off with AsyncTask instead of Thread.

Related

How to run tasks at a scheduled rate that DON'T wait for the task before it?

Currently, I have some code that I need to run every (for example) 33 milliseconds. However, the operation that I am calling requires around 270ms. Is there a way to schedule my tasks so that they run regardless of the task before them?
I have tried implementing a ScheduledExecutorService variable and running the task at a "ScheduledFixedRate" but that currently waits for the task before it.
Runnable imageCapture = new Runnable() {
public void run() {
// code that takes approximately 270ms
}
};
executor = Executors.newScheduledThreadPool(4);
executor.scheduleAtFixedRate(imageCapture, 0, 33, TimeUnit.MILLISECONDS);
Split the task in two: one makes actual computations and another is executed periodically and starts the first one:
executor = Executors.newScheduledThreadPool(4);
Runnable imageCapture = new Runnable() {
public void run() {
// code that takes approximately 270ms
}
};
Runnable launcher = new Runnable() {
public void run() {
executor.execute(imageCapture);
}
};
executor.scheduleAtFixedRate(launcher, 0, 33, TimeUnit.MILLISECONDS);

CountDownLatch.await() suspending background threads

I'm working on an android app which at some point runs a service. That service runs a new thread for a time-consuming operation and waits for a countDownLatch to be zero. After that it runs a second thread for another time-consuming operation (that new thread isn't really necessary now but will be in the near future).
Now...after starting the downloadThread, if I do the waiting as shown below, the main thread AND the downloadThread suspend operations. However, if I wait for the countDownLatch inside the uploadThread everything works fine.
Thread downloadThread = new Thread(new Runnable() {
#Override
public void run() {
downloadFiles(mMediaFileList);
}
});
downloadThread.start();
try {
Log.d("UploadMedia", "Waiting for DownloadMedia to finish");
mCountDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread uploadThread = new Thread(new Runnable() {
#Override
public void run() {
uploadMedia();
}
});
uploadThread.start();
It's not really a problem but isn't it supposed to work both ways? Is there something I'm missing about the .await() functionality?
Cheers!
Edit: FYI, downloadFiles has callbacks which wait for completion or failure of the task. Can it be that those callbacks work on the main thread which is being suspended by the .await()?
It's not evident where your latch gets count down. But it sounds as it happens during uploadMedia(). If so, your main thread gets stale at latch.await() because there is no other controlflow that could count the latch down to zero.

ScheduledExecutorService running many threads when I created it using Executors.newSingleThreadScheduledExecutor

Context:
This is a Jersey application
Run on a Tomcat server
Connects to a MySQL database using Hibernate
All on Netbeans
I'm creating a ScheduledExecutorService to run everyday at a particular time. However, when it runs it creates many connections to the database. I imagine it's because the threads aren't being destroyed when I rerun the application, so many ScheduledExecutorServices build up in the JVM and all execute at the same time. But, I'm not sure what the cause is.
I create the ScheduledExecutorService with a ThreadFactory that only creates daemon threads, so when I rerun the application I imagine that all daemon threads should be destroyed so that only one ScheduledExecutorService ever exists.
Here is the creation of the ScheduledExecutorService:
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
Here is how it runs everyday at a particular time:
public void startExecutionAt(int targetHour, int targetMin, int targetSec){
long delay = computeNextDelay(targetHour, targetMin, targetSec);
mExecutorService.schedule(new Runnable() {
#Override
public void run() {
Thread t = new Thread(new CustomRunnable());
t.setDaemon(false);
t.start();
startExecutionAt(targetHour, targetMin, targetSec);
}
}, delay, TimeUnit.SECONDS);
}
I know it's creating many connections to MySQL because in the P6Spy log there are many many connections and queries made when CustomRunnable is executed when CustomRunnable only runs one Hibernate query that selects 5 records from a table.
Any ideas as to what could be going on?
You obviously misuse your ScheduledExecutorService, here is what you are supposed to do:
public void startExecutionAt(int targetHour, int targetMin, int targetSec){
long delay = computeNextDelay(targetHour, targetMin, targetSec);
mExecutorService.scheduleAtFixedRate(
new CustomRunnable(),
1000L * delay,
TimeUnit.DAYS.toMillis(1),
TimeUnit.MILLISECONDS
);
}
You call this method once for all and it will launch your task with delay as initial delay then every day at the same exact time.
More details here.
Indeed you currently create a new thread any time the task is executed then call again the method to schedule the next execution which is not what you are supposed to do, the task is already executed in a pool no need to create a new Thread moreover no need to schedule again manually when you can do it directly with the ScheduledExecutorService.
Response Update:
As the scheduling seems to be more complicated in your case, here is how you should do it instead:
public void startExecutionAt(int targetHour, int targetMin, int targetSec){
long delay = computeNextDelay(targetHour, targetMin, targetSec);
mExecutorService.schedule(new Runnable() {
#Override
public void run() {
try {
new CustomRunnable().run();
} finally {
startExecutionAt(targetHour, targetMin, targetSec);
}
}
}, delay, TimeUnit.SECONDS);
}
This way you won't create and start new threads for nothing.
The second part of your problem should be fixed by starting and shutting down properly your ScheduledExecutorService respectively on ServletContext initialized and destroyed, in other words the class that manages your scheduler should be a ServletContextListener.
public class MyServletContextListener implements ServletContextListener {
private ScheduledExecutorService executorService;
public void contextInitialized(ServletContextEvent sce) {
executorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
}
public void contextDestroyed(ServletContextEvent sce) {
executorService.shutdownNow();
}
public void startExecutionAt(int targetHour, int targetMin, int targetSec){
// code defined above here
}
}
If you need services to make it work, use CDI to get them by injection.

Start a thread a second time

thread = new Thread()
{
#Override
public void run() {
while(!requestedToExit)
{
SystemClock.sleep(3000);
Log.d("debug", "in");
}
}
};
So a button got an event, Each time I click on it it's start the thread (if the previous thread is not alive).
So I tried use thread.start() but it throw thread already started. I tried .run(), nothing happens, I also tried each time I click on the button, and it's possible to run it again, create a new thread and start it : nothing.
Some ideas ?
Using Runnable :
r= new Runnable(){
public void run() {
while(!requestedToExit)
{
Log.d("debug", "in");
SystemClock.sleep(3000);
}
}
};
Then I use in my listener :
thread = new Thread(injection);
thread.start();
But I only see the debug the first time, he never enter into it after.
Thanks in advance
From the JavaDoc -
It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution.
Instead, use java.lang.Runnable and create a new thread to run it when you have to.
What you need to do is:
Runnable r = new Runnable() {
public void run() {
....
}
};
Then, when you want to start it:
Thread t = new Thread(r);
t.start();
You need to always create a new thread to run that one runnable.

Run a class instance as a thread by itself

I have this piece of code:
Timeout s = new Timeout();
Timer timer = new Timer();
timer.schedule(s, 1000L); // fires after 1 second
How can I launch the following piece of code as a thread by itself? Would I need to pass the timer and Timeout to a Runnable and then start it? What happens if the thread's Run() ends before the timer is fired?
I am thinking of doing this instead:
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Timeout s = new Timeout(); // Timeout is a runnable
ses.schedule(s, 10, TimeUnit.SECONDS);
but how do I exit the thread after the timeout? I run out of thread after a while
Thanks
I'm not exactly sure what you're asking, but I'll give it a shot.
How can I launch the following piece of code as a thread by itself?
In short...
Timeout.java
public class Timeout extends TimerTask {
boolean isDone = false;
#Override
public void run() {
// TODO something
synchronized(this) {
isDone=true;
this.notifyAll();
}
}
public synchronized void join() throws InterruptedException {
while(!this.isDone)
this.wait();
}
}
TimeoutRunner.java
public class TimerRunner implements Runnable {
#Override
public void run() {
Timeout timeout = new Timeout();
Timer timer = new Timer();
timer.schedule(timeout, 1000L);
try {
timeout.join();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
timer.cancel();
}
}
}
Run the TimeoutRunner using:
new Thread(new TimeoutRunner()).start();
The join method will block the thread until the timeout task has completed execution. At that time you can close the Timer. This is, however, a lot of thread creation, and IMO bad programming.
When you create a Timer instance, a thread is created to execute the Timeout#run() method. The timer has it's own run method that blocks until your task is ready for execution. After the given timeout period elapses, the timer unblocks and executes your timeout.
Your TimeoutRunner thread will block until the timeout operation completes. Only then can this thread die.
The Timer class is very limited. You need to create a new instance for every task. In my option, the ScheduledExecutorService is a better option. Keep the ScheduledExecutorService open for as long as you plan on executing tasks. If you need something like a scheduled cached thread pool, feel free to use this class from one of my open-source projects (Scheduler). This works great with a cached thread pool.

Categories