Is there a way to check if a Thread object has had start called on it already?
I'm trying to so something like:
if(rt.isAlive() == true)
{
Log.v(TAG, "START RECORD");
rt.recording = true;
}
else
{
Log.v(TAG, "START THREAD/RECORD");
rt.start();
}
where it would start the thread if it's not already running.
Assuming that rt is a Thread, just check rt.isAlive().
Alternatively, just use a boolean flag and set it to true right before you start your thread.
I would actually prefer the boolean approach so there is no way that the main thread could start the other thread twice - there may be a short delay until your Thread is up and running, and if your main thread tries to start the thread twice in quick succession, it may get a "false" negative on rt.isAlive().
I've used this approach with success:
if ( mythread.getState() == Thead.State.NEW )
//then we have a brand new thread not started yet, lets start it
mythread.start();
else
//it is running already compensate
If you called start on it, and it is running, you will get an IllegalThreadStateException. Catching that is one way to know.
Another option is to extend Thread and add a boolean where you keep track of whether or not your Thread has been started. You can override the start method of Thread to check the boolean before calling up to super.start().
You should be very careful when using threads in Android though. Make sure you understand the lifecycle of the component that is starting it. Also, you should consider some of the helper classes like Handler and AsyncTask instead of directly spawning threads.
Call this method by passing a thread. It will check the thread is alive or not, every 500 milliseconds with start delay of 500 milliseconds (you can use your custom values). I use this method often.
void threadAliveChecker(final Thread thread) {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if (!thread.isAlive()) {
// do your work after thread finish
runOnUiThread(new Runnable() {
#Override
public void run() {
// do the ui work here
}
});
timer.cancel();
}else {
// do work when thread is running like show progress bar
}
}
}, 500, 500); // first is delay, second is period
}
Example:
Thread thread = new Thread(myRunnable);
thread.start();
threadIsAliveChecker(thread);
This method will let us know when the thread is finished doing its work.
Related
I have 2 question regarding on Thread, I just want to clarify something. With the below code:
public class MyThread implements Runnable {
Boolean StopThread = false;
Boolean DontLoop = false;
public MyThread(){}
public void Stop(Boolean stopThread){
this.StopThread = stopThread;
}
public void ThreadDontLoop(Boolean dontLoop){
this.DontLoop = dontLoop;
}
public void run(){
if(dontLoop){
while(true){
if(StopThread){
break; //Terminate WhileLoop, This will Stop and destroy the Thread also
}
}
}else{
//Does this mean the Thread will be destroy/terminate after this condition?
}
}
}
In order to Start:
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
In order to Start Thread but Don't Loop
ThreadDontLoop(false);
thread.start();
In order to Stop the Thread
myThread.Stop(true);
Now, According to this LINK, that's how the thread to be stopped.
So my first question is, in the Given code above, what if I call ThreadDontLoop(false); then thread.start();, does this mean the Thread will Start but after the condition, the Thread will be stopped and destroy?
Second question is, Let's say I call thread.start(); then later I call myThread.Stop(true); to stop the WhileLoop and Destroy the Thread.
I didn't follow on how the link is stopped the thread since I will have a different condition, but I believe that the logic on how I would like to stop the Thread is correct?
You need a volatile boolean or the value can be inlined and never appear to change.
in the Given code above, what if I call ThreadDontLoop(false); then thread.start();, does this mean the Thread will Start but after the condition, the Thread will be stopped and destroy?
Yes.
Let's say I call thread.start(); then later I call myThread.Stop(true); to stop the WhileLoop and Destroy the Thread. I didn't follow on how the link is stopped the thread since I will have a different condition, but I believe that the logic on how I would like to stop the Thread is correct?
If you don't have a visibility issue (does the thread see your change) it will stop. In the code you have in the question, most likely the code will be optimised to assume the thread never sees the change.
I created a thread like this:
private Thread t = new Thread() {
#Override
public void run() {
try {
while(true) {
// do work
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
}
}
};
t.start();
Then i interrupted it using t.interrupt().
As soon the thread stops and get on sleep() it will interrupt and become unusable, but will it stay on memory?
Do i have to call t = null, or the GC will take care of that?
I'm trying to dynamically interrupt the thread and recreate it when needed (using t = new Thread()), but im not sure if just interrupt() removes the old thread from memory. I've searched but couldn't find this specfic answer.
The Thread class is a proxy for the OS Thread. Before you call start() there is no actual OS thread and after the thread stops it is cleaned up even if you hold on to the Thread object. At this point it just like any other object and it will be cleaned up in the normal way.
Seems you are using this code snippet inside a method thus Thread t becomes local variable and it will be cleared by gc , just make sure you don't use this reference variable further down in the method.
If my thread receives an InterruptedException in a sleep(), how can I tell whether it was caused by a call on its .interrupt() or .notify() method?
The long story:
I have a View() class running in a thread. It should run worker(s) and update the view from time to time. It should also measure the time the worker took. The View() should be interruptable by the application (upon shutdown). The workers should wake up (notify) the thread during sleep when they have finished to measure the time they took. (Without notification, time measured would be rounded up to the next full sleep cycle which isn’t desired.) So an InterruptedException can be triggered by a call on the thread’s .interrupt() or .notify() method. How do I distinguish this inside the catch block?
public class View() implements Runnable {
Long started = null;
Long finished = null;
#Overload
public void run(){
Set<Thread> workers = new HashSet<Thread>();
for(int i = 1; i <= 5; i++){
Thread worker = new Thread(new Worker());
worker.start();
workers.add(worker);
}
started = System.getCurrentTimeMillis();
do{
try{
TimeUnit.SECONDS.sleep(3);
updateView();
}catch(InterruptedException e){
if(--> thread_was_notified <--){
finished = System.getCurrentTimeMillis();
updateView();
}
if(--> thread_was_notified <--){
for(Thread worker : workers)
worker.interrupt();
}
return;
}
}while(true);
}
protected void updateView(){
// …
}
}
I first guessed that InterruptedException would have Subclasses, but there are none directly known subclasses listet in the javadoc. Thread provides .isInterrupted(), but as said here: “By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so.” So I can’t tell from .isInterrupted() either. What’s the clean way to do it?
I have a vegue idea that my code should use Object.wait(), but what’s the waiting object?
The ugly solution:
Instead of having your Workers interrupting the View thread, put a method like this:
public void workedFinished() {
interruptedByWorker = true; // View attribute.
viewThread.interrupt(); // Interrupt the view
}
Then, when you're on your catch, check for the interruptedByWorker boolean. If it is true, it was interrupted by a worker. Otherwise (make sure this is happens), it was interrupted by the shutdown.
The other solution
Instead of interrupting the thread in two different places (which I think it could be confusing an error-prone), you could do the following:
1) Schedule a Runnable to run every 3 seconds using a ScheduledExecutorService to update the view.
2) Have a CountdownLatch that is notified for each Worker that finishes. Please, notice that in your code, the first thread wakes up the View, meaning that the measured time will be only for that thread, it will not wait until the other threads finish.
InterruptedException is only thrown when some thread interrupts you and not thrown when comming out of wait().
So when you are in sleep() or wait() and some other thread decides to interrupt you then Exception will be thrown.
When a thread is in wait() state and notify() is called for it then it will again fetch the lock and resume its working without throwing any exception.
I have two tasks that should be run together.
The first task to save the data to the database. And the second task of recording video.
Currently I use a Thread for each task, and run it simultaneously.
...
Thread insertDb = new Thread(new Runnable() {
#Override
public void run() {
// Insert to Database
setDataMediaVisit(thumbStr);
insertVisitRecord();
}
});
Thread capture = new Thread(new Runnable() {
#Override
public void run() {
if (getGraph().getState() == DSCapture.PREVIEW) {
getGraph().setCaptureFile("data/"+ CaptureController.getNoMr() +"/videos/"+videoStr, DSFilterInfo.filterInfoForProfile(new File("profiles/demo_profile800x570_WM8_VBR_100.prx")), DSFilterInfo.doNotRender(), true);
getGraph().record();
}
setData(CaptureController.getNoMr());
}
});
insertDb.start();
capture.start();
...
Is the above code thread safe?
I want to use EDT, but i know EDT for Java Swing Component. CMIIW
Thank you.
THread safe is just an issue, when do you want use object that are running in specific thread with another thread. It's not clear here that you are using the share object in this 2 thread or not! But, if you wanna use some share object or you want to read and write from file or specific butter, you can use lock object like this:
final Object lock = new Object();
// In thread 1
// TODO: do some process in thread on
synchronized(lock) {
// TODO: Put the result in somewhere that thread2 want to read it
}
// In thread 2
synchronized(lock) {
// TODO: get the result from the place that you put in thread 1
}
// TODO: do some process on thread 2 on the data
You should always remember that you need to put smallest possible synchronized, because if the other thread reach to synchronized part, it will wait until thread 1 finish synchronized block and it can kill the performance of your code
The basic idea is that I have a native function I want to call in a background thread with a user selected value and the thread cannot be interrupted when started. If the user decides to change the value used to perform the task while the thread is running (they can do this from a GUI), the thread should finish its task with the previous value and then restart with the new value. When the task is done and the value hasn't changed, the thread should end and call a callback function.
This is what my current code looks like for the thread starting part:
volatile int taskValue;
volatile boolean taskShouldRestart;
void setTaskValue(int value)
{
taskValue = value;
synchronized (threadShouldRestart)
{
if task thread is already running
threadShouldRestart = true
else
{
threadShouldRestart = false
create and start new thread
}
}
}
And the actual work thread looks like this:
while (true)
{
nativeFunctionCall(taskValue);
synchronized (threadShouldRestart)
{
if (!threadShouldRestart)
{
invokeTaskCompletedCallbackFunction();
return;
}
}
}
I'm locking on the "threadShouldRestart" part because e.g. I don't want this changing to true just as the thread decides it's done which means the thread wouldn't restart when it was meant to.
Are there any cleaner ways to do this or Java utility classes I could be using?
You could design your run() method as follows:
public void run() {
int currentTaskValue;
do {
currentTaskValue = taskValue;
// perform the work...
} while (currentTaskValue != taskValue);
}
I think the volatile declaration on taskValue is enough for this, since reads and writes of primitives no larger than 32 bits are atomic.
Have you considered a ThreadPoolExecutor? It seems to lend itself well to your problem as you mentioned you have no need to restart or stop a thread which has already started.
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
A user could submit as many tasks as they like to a task queue, tasks will be processed concurrently by some number of worker threads you define in the ThreadPoolExecutor constructor.