I am new in java Android... I am trying to create two threads (named: Clean and Progress) that will run two different methods each method get the same object mix.while Clean will run a time consuming method that is part of mix's class (mix.TimeConsumingMethod();) I want Progress thread to monitor the progress of TimeConsumingMethod() by checking class variables such as mix.length and mix.framesClean
in progress I check to see mix.length > 0 if not I want Progress to wait over here my app crashes and in log CAT i get an error of:
09-20 10:37:32.773: E/AndroidRuntime(12030): java.lang.IllegalMonitorStateException: object not locked by thread before wait()
snippet of code invoking both threads:.
mix = new MixMaxMain();
progressThread = new Thread(new Runnable() {
#Override
public void run() {
Progress (mix);
}
},"Progress Thread");
CleanThread = new Thread(new Runnable() {
#Override
public void run() {
Clean (mix);
}
},"Cleaner Thread");
Log.d("STOP", "SEnding cleanThread AND progress Thread");
CleanThread.start();
progressThread.run();
snippet of Clean running time consuming method:
long time_start = SystemClock.elapsedRealtime();
mix.Run(Daudio,mu,sigSqr,c);
long time_end = SystemClock.elapsedRealtime();
snippet of Progress:
while(mix.length==0) {try {
Log.d("Progress", "Length is Zero");
Thread.sleep(1);//fails here!!
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
Log.d("Progress", "Clean Has Started");
int totalProgressLen = (int)(mix.length+0.7*mix.length);
while(mix.done==false)
{
try {
progressThread.wait(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
progress.setProgress(mix.framsClean*256/totalProgressLen );
}
You get the IllegalMonitorStateException if the thread you're calling wait on does not own the lock on the monitor you're calling it on.
To do this, you can surround the wait() call in a synchronized block. In your case, it would be something like:
synchronized(progressThread){
progressThread.wait(50);
}
There is also a way to check for this with the holdsLock(Object obj) method, which will return true only if the current thread holds the monitor lock on the specified object.
For full details, take a look at the Java Documentation on wait() for an Object.
Related
I've an object that's created when the class is instantiated. I create a lock i-e; wait() on that object inside a background thread, however the app still gets unresponsive. My understanding of synchronization/locking is that if object.wait() is called in the main thread than it's equivalent to blocking the main thread however if it's called inside a background thread (even though the object upon which wait() is called in the main thread, shouldn't cause problems).
Can someone please help me out understanding this?
Example code:
class MyClass {
private final Object myLockObject = new Object();
public void connect() {
new Thread(new Runnable{
mSocket.connect();
myLockObject.wait(); // causing ANR
}).start();
}
private void socketConnectCallback() {
//upon callback
myLockObject.notifyAll();
}
}
class MyAndroidService extends Service {
public void onStartCommand() {
MyClass myClassObject = new MyClass();
myClassObject.connect();
//it immediately returns here even with the code written above.
}
}
First of all, this code will throw an IllegalMonitorStateException. This is because before calling object.wait(), you need to make sure that you are holding the object's monitor. One way to do this is to use:
synchronised(object) {
// this thread now owns the object's monitor
object.wait();
}
Further, the thread that calls for object.wait() relinquishes its ownership on that object's monitor and waits for some other thread to notify it. Once it gets the notification, it will wait until it reacquires the object's monitor (since some other thread might be having the ownership of that monitor even if the waiting thread got the notify signal). Then it continues normal execution.
In your case, the background thread should block, and the main thread should continue executing normally. Isn't this what you have mentioned is happening?
I don't know if this will help so much, but I can't comment so I want to get your attention to this code:
newThread(new Runnable {
mSocket.connect();
myLockObject.wait();
}).start();
This must be like:
(new Thread( new Runnable() {
public void run() {
try {
mSocket.connect(); // connect takes argument(s)
} catch (IOException e) {
// Catch the excpetion
}
try {
myLockObject.wait();
} catch (InterruptedException e) {
// Catch the excpetion
}
}
})).start();
and since Runnable is a functional interface you can use lambda expression instead of creating a new object.
Edit:
I think I figured out what do you want to do, if you want to make a thread that connects the socket and then wait to be notified and want it to acquire the intrinsic lock of the object myLockObject to prevent interleaving then you have to put the code you want to be executed by the thread in a guarded block:
private final void connectSocket() {
synchronized(myLockObject) {
try {
mSocket.connect(null);
} catch (IOException e) {
}
try {
myLockObject.wait();
} catch (InterruptedException e) {
}
}
}
and in the connect method just call connectSocket
public void connect() {
new Thread(new Runnable() {
public void run() {
connectSocket();
}
}).start();
}
I am starting these threads:
ThreadingHDFSUsage HDFSUsage=new ThreadingHDFSUsage(dcaps);
ThreadingRAMandContainers RAMandContainers=new ThreadingRAMandContainers(dcaps);
ThreadingCoreNodesHDFSUsage CoreNodesHDFSUsage=new ThreadingCoreNodesHDFSUsage(dcaps);
ThreadingApplicationMonitoring ApplicationMonitoring= new ThreadingApplicationMonitoring(dcaps);
How should i wait for all these threads to complete before doing some other operation.
My sample thread class code for one thread operation is:
public class ThreadingHDFSUsage extends Thread {
//private PhantomJSDriver driver;
private DesiredCapabilities dcaps;
public ThreadingHDFSUsage(DesiredCapabilities dcaps) {
// TODO Auto-generated constructor stub
this.dcaps = dcaps;
}
public void run(){
System.out.println("task HDFS Usage");
PhantomJSDriver driver = new PhantomJSDriver(dcaps);
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(".........HDFS Usage..........");
String OverallHDFSUsage[] = null;
try {
OverallHDFSUsage = HDFSUsage.getWebData(driver,"http://1.2.3.4:8888/dfshealth.html#tab-overview","//*[#id=\"tab-overview\"]/table[2]/tbody/tr[2]/td","");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String OverallHDFSUsage1 = OverallHDFSUsage[0];
}
}
Similarly, I have relevant code for other threads.
So, how do i wait for all these 4 thread operation to complete?
Just join() them again:
HDFSUsage.join();
RAMandContainers.join();
CoreNodesHDFSUsage.join();
ApplicationMonitoring.join();
Each join() waits for the specific thread to finish.
There's also CompletionService in JDK concurrent package. To use it, you switch from explicit Threads to tasks, represented as instances of Callable<ResultType> or Runnable. While code may look slightly more complicated, it is quite convenient, once you became used to it:
import java.util.concurrent.*;
class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletionService<String> completionService = new ExecutorCompletionService<>(Executors.newCachedThreadPool());
completionService.submit(() -> {
Thread.sleep(5000);
return "sleeped for 5000 millis";
});
completionService.submit(() -> {
Thread.sleep(1000);
return "sleeped for 1000 millis";
});
// etc
System.out.println("Completed: " + completionService.take().get());
System.out.println("Completed: " + completionService.take().get());
}
}
Both of the other answers are correct, but for completeness, there's yet another way to do what you want using a Semaphore. This method won't yield results different from any of the other answers, but may be faster if any of your threads have to do something expensive after the results you want are obtained, prior to returning. Inside each of your threads, call s.release() as soon as all pertinent work is finished. Your controller thread might look like this ...
Semaphore s = new Semaphore(0);
//start all four of your threads here and pass 's' to each
s.acquire(4);
... and your worker threads might look like this:
#Override
public void run(){
//compute results
s.release(1);
//do expensive cleanup and return
}
Why is another "TaskImpl run()" in Scenario 1 below missing ?
Scenario 1: if the line marked with 1. is before the line marked with 2. this is shown in the console:
TaskImpl run()
ThreadImpl run()
ThreadImpl run()
Finished
Scenario 2: If the line marked with 2. is before the line marked with 1. this is shown in the console:
TaskImpl run()
TaskImpl run()
ThreadImpl run()
ThreadImpl run()
Finished
My code :
public class ThreadTest {
public static void main(String[] args)
{
Thread t1 = new ThreadImpl();
Thread t2 = new Thread(new TaskImpl());
t1.start();
t2.start();
t1.run(); // 1.
t2.run(); // 2.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Finished");
}
}
class ThreadImpl extends Thread {
#Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("ThreadImpl run()");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class TaskImpl implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("TaskImpl run()");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
As you can see in the implementation of Thread#run the run method of the target (the Thread implementation/subclass which should be run in a thread) will only be called if target is not null:
#Override
public void run() {
if (target != null) {
target.run();
}
}
Now another info: If a thread has done its job it calls the private exit method which sets target to null (*):
private void exit() {
// [omitted code lines]
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
// [omitted code lines]
}
So if you called start on a Thread and it has done its job, then you can't call run again ... well you can, but I won't do much.
Now let's look at your first version of your code:
t1.start(); -> starts a thread; takes at least 2 seconds to finish
t2.start(); -> starts a thread; takes at least 1 second to finish
t1.run(); -> blocks main thread; takes at least 2 seconds to finish
t2.run(); -> called after `t1.run()` finished;
So as you can see, t2.run() will run at least 2 seconds after t2.start() because t1.run() blocks the method call. So t2 (from t2.start()) already finished and set target to null so t2.run() fails the target != null check and does "nothing".
Now the second version:
t1.start(); -> starts a thread; takes at least 2 seconds to finish
t2.start(); -> starts a thread; takes at least 1 second to finish
t2.run(); -> blocks main thread; takes at least 1 seconds to finish
t1.run(); -> called after `t2.run()` finished;
Here t2.run() can run before t2 from t2.start() could have finished his "sleep" so target is still set correctly.
And t1.run() also has no problem, because it directly calls the overriden run method of ThreadImpl, so it doesn't need to pass the check. And it wouldn't have a problem to pass it anyway, because t2.run() sleeps for 1 second, so t1 from t1.start() still sleeps for another second and his target is also still set.
That is why you get the "full" output.
I hope my explanation is clear and you understand the cause for the different output :).
(*) Please mind that this behavior my vary in other Java Environments. But the Oracles version and OpenJDK are doing that.
I have a following code.
ReadWriteLock someLock = new ReentrantReadWriteLock();
Condition someCondition = someLock.writeLock().newCondition();
public someMethod() {
// do some stuff
someCondition.await(); //Lock here.
System.out.prinltn("This never prints");
}
public doSomeStuff() {
new Thread(new Runnable() {
#Override
public void run() {
try {
someMethod();
System.out.println("thread finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread is going to die");
}
}).start();
}
When the thread calls the method someMethod() it gets executed. But since there is an await() method on that function. It never ends / it does not print 'This never prints', unless its woken up by singnalAll(). But I want the thread to be finished once its executed.
I cannot refactor the whole thing. I just need a workaround to this problem. Its used in Swing application. So thread is important.
I think, this will do:
Thread thread =
new Thread(new Runnable() {
#Override
public void run() {
try {
someMethod();
System.out.println("thread finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread is going to die");
}
});
thread.start( );
final long reasonableTimeout = ...;
thread.join( reasonableTimeout );
// THIS WILL SHAKE IT UP
thread.interrupt( );
thread.join( );
// At this point, it is guaranteed that the thread has finished
I am not sure if I understood your question correctly but I think you want to start the someMethod() function and then make the caller exit without waiting for someMethod() to finish. This means you are basically branching your execution flow into two, one where the someMethod() running waiting for its due awakening and the other where the caller just continues on(which it will need to do if you want it to finish) after calling someMethod(). To do this you will have to run someMethod() in a separate thread. Something like this.
public doSomeStuff() {
new Thread(new Runnable() {
#Override
public void run() {
try {
new Thread(){
public void run(){
someMethod();
}
}.start();
System.out.println("thread finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread is going to die");
}
}).start();
}
Two ways you can sort this out.
1) Design your task with Interruption Policy
Do a defensive coding. If your task is interrupted by any means, the program should know how to deal with that.
2) Add a POISON PILL as in this example, Once you
public someMethod() {
while(condition predicate){
someCondition.await(TIME_OUT); //Lock here.
}
//ADD Poison pill here
System.out.prinltn("This never prints");
}
As Per Java Concurrency in Practice
When using condition waits (Object.wait or Condition.await):
1)Always have a condition predicate some test of object state that must hold before
proceeding;
2)Always test the condition predicate before calling wait, and again after returning from
wait;
3)Always call wait in a loop;
4)Ensure that the state variables making up the condition predicate are guarded by the lock
associated with the condition queue;
5) Hold the lock associated with the the condition queue when calling wait, notify, or
notifyAll; and
6)Do not release the lock after checking the condition predicate but before acting on it.
I have checked different questions in this and in other forums, but I didn't find the solution to my problem.
I have an application which runs ffmpeg and exiftool processes. I have concurrency probles, and I would like to control them, using Thread. This is how I built it:
ExiftoolThread
public class ExiftoolThread extends Thread{
String file;
public ExiftoolThread(String file){
this.file = file;
}
public void run(){
serviceToExiftool(file);//Create metadata file
}
}
FfmpegThread
public class FfmpegThread extends Thread{
String itemName;
public FfmpegThread(String itemName){
this.itemName = itemName;
}
public void run(){
serviceFFmpeg(itemName);//Create thumbnai froma video
}
}
Main call
Thread exiftoolThread = new ExiftoolThread(file.getName());
exiftoolThread.run();
try {
exiftoolThread.join(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.write("JSON file created.It contains the metadata. ");
Thread ffmpegThread = new FfmpegThread(itemName);
ffmpegThread.run();
try {
ffmpegThread.join(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.write("Thumbnail created successfully. ");
After this call finishes, there are more actions working with the results of these processes, and there is always one of them which is missed. I guess that's because one of them (exiftool or ffmpeg) finishes earlier and then the process continue before the other finishes.
I am using ffmpegThread.join(3000); to skip this problem, as the documentation says, this method waits untill the thread is died. What am I missing?
Thanks in advance
You need to call Thread.start() instead of Thread.run() on your two threads. The start() method actually spins a new thread to execute code concurrently, while the run() method is a normal method that executes in the calling thread like any other.
additionally, you can improve your thread synchronization setup by replacing the join() calls by use of a java.util.concurrent.CountDownLatch. Your main code will look like this:
CountDownLatch latch = new CountDownLatch(2);
Thread ffmpegThread = new FfmpegThread(itemName, latch);
Thread exifToolThread = new ExifToolThread(itemName, latch);
ffmpegThread.start();
exifToolThread.start();
latch.await(); // With optional timeout
Your two helper threads must both call latch.countDown() when they're done.
You have to call start() to run the code in the new thread. Also, join() block the current thread, so you have to call it after you start all your thread.