My function has to return data just after my thread end, I am using the wait() method after start() my thread but it doesn't work :
private class getDataThread extends Thread {
#Override
public void run() {
super.run();
while (true) {
try {
// ...
Thread.sleep(100);
} catch (InterruptedException e) {
// ...
}
}
}
}
public void getSensorValues(Bundle bundle) {
// ...
getDataThread gdt = new getDataThread();
gdt.start();
try {
gdt.wait();
} catch (InterruptedException e) {
// ...
}
}
in LogCat :
: An exception occurred during execution !
: Exception caught: java.lang.reflect.InvocationTargetException
: Exception cause: (SYSTEM) java.lang.IllegalMonitorStateException: object not locked by thread before wait() in getSensorValues
: status::FAILURE - output:: Possible errors: (SYSTEM) java.lang.IllegalMonitorStateException: object not locked by thread before wait() in getSensorValues.
What I'm doing wrong?
You're looking for join, not wait:
public void getSensorValues(Bundle bundle) {
// ...
getDataThread gdt = new getDataThread();
gdt.start();
try {
gdt.join();
} catch (InterruptedException e) {
// ...
}
}
wait has a different purpose, which is to signal another thread that an event has occurred. It requires a matching call to notify. Furthermore, you need to acquire the lock on the object which is being used to wait/notify, which is why you are getting that exception.
And another thing: starting a thread and then immediately joining it is redundant. You might as well execute everything on the main thread.
wait() does not wait for a thread to finish. It waits for another thread to call notify() or notifyAll().
Instead, you need to use join() so that the other thread will join the current thread. The current thread will block until the other thread finishes.
That said, both wait() and notify() need to be inside a synchronized block for the object being used. Example:
synchronized (lock) {
lock.wait();
}
Related
I implemented this class in my android code
I made the below change in the run method(replaced "true"):
#Override
public void run() {
while (!isInterrupted()) {
try {
// A blocking operation. Initiate a ChatManager instance when
// there is a new connection
pool.execute(new ChatManager(socket.accept(), handler));
Log.d(TAG, "Launching the I/O handler");
} catch (IOException e) {
try {
if (socket != null && !socket.isClosed())
socket.close();
} catch (IOException ioe) {
}
e.printStackTrace();
pool.shutdownNow();
break;
}
}
}
I want to stop this thread before I close the app. So I implemented threadName.interrupt(); method. But this doesn't interrupt the thread.
I am actually confused with the usage of thread pool executor. So I am not sure how to do this efficiently. How can I implement interrupting this thread? When interrupt method is called, I want to close the socket, shutdown the pool and stop the thread.
Thread thread = new Thread () {
boolean isRunning = true;
public void stopThread() {
isRunning = false;
}
#Override
public void run() {
while (isRunning) {
try {
// A blocking operation. Initiate a ChatManager instance when
// there is a new connection
pool.execute(new ChatManager(socket.accept(), handler));
Log.d(TAG, "Launching the I/O handler");
} catch (IOException e) {
try {
if (socket != null && !socket.isClosed())
socket.close();
} catch (IOException ioe) {
}
e.printStackTrace();
pool.shutdownNow();
break;
}
}
}
};
thread.start();
Try this code. and call thread.stopThread() whenever you want the thread to stop.
if you want close an Android thread, you can set a variable to control run(),because run() is end, the thread will be closed.
The code is something like:
final boolean istrue=true;
new Thread(new Runnable() {
#Override
public void run() {
while (istrue){
//TODO your work
}
}
}).start();
}
If you want to close the thread, you only set istrue=false
Just call shutDownNow to close the pool and try interrupt all the threads inside it. You can check the difference in this post:
shutdown() will just tell the executor service that it can't accept new tasks, but the already submitted tasks continue to run
shutdownNow() will do the same AND will try to cancel the already submitted tasks by interrupting the relevant threads. Note that if
your tasks ignore the interruption, shutdownNow will behave exactly
the same way as shutdown.
If you want to interrupt or cancel an specific thread. I suggest you to use submit with Callables, With this, you will me able to work with your Future object, then if want to cancel a task you've given an executor service, you can call cancel(true) on its associated Future. When your task detects an interrupt request, it should preserve the interrupted status by calling Thread.currentThread().interrupt().
I am getting this error, and my application crashes:
java.lang.IllegalStateException: The current thread must have a looper!
I didn't get much about how to use looper on Google, I am using threads(mainly for sleep function), handler(for downloading the image while Async task is running) and Async task(for getting the JSON data from the URL). I have no idea how to resolve this issue, so any suggestions will be vey helpful.
This is the code for the thread which is executed on click of the button:
View view = flingContainer.getSelectedView();
view.findViewById(R.id.item_swipe_right_indicator).setAlpha((float) 1.0);
Thread timer = new Thread() {
public void run() {
try {
sleep(320);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
flingContainer.getTopCardListener().selectLeft();
}
}
};
timer.start();
I am using this libray and log-cat is:
where: at com.enormous.quotesgram.MainActivity$3.run(MainActivity.java:479) in last in log-cat corresponds to the line: flingContainer.getTopCardListener().selectLeft(); in above piece of code.
Try the following (unfortunately I cannot test the code):
Thread timer = new Thread() {
public void run() {
try {
sleep(320);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
runOnUiThread(new Runnable() {
#Override
public void run() {
flingContainer.getTopCardListener().selectLeft();
}
});
}
}
};
The idea behind is, that the Timer thread is not a Looper thread (resulting in an exception saying "The current thread must have a looper"). The UI thread however, is a Looper thread (see for instance this site).
As flingContainer.getTopCardListener().selectLeft() is probably designed to run on the UI thread it fails, if it not invoked in side of a pipelined thread.
I'm working on a service and I had the following code in onStartCommand:
try {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Networker.get("http://google.com/");
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.run();
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Even though the networking code is running in another thread, my service still crashed with the NetworkOnMainThreadException. The equivalent AsyncTask code does not cause this error. Is it because of the join?
I was doing this because I only need my service to run a single request and then quit, so I wanted to use the code above and return START_NON_STICKY to make the service close quickly again. Am I supposed to be doing something else instead?
Call start() and not run() on the thread to start the thread.
run() will just run your Runnable in the current thread.
I have a basic asynchronous task that performs a web request. The thread is not contained in a loop or anything, it performs the request and returns from run(). When I try to execute another request, using that thread, I get an exception thrown because the thread is already running. I've searched around a lot on this site for answers, but all that seems to come up is stopping threads that are in a loop, basically forcing the thread to return.
Should I just put the request code in the thread into a loop that waits on some kind of flag from the main thread to tell it to go ahead and execute again? like:
public void run()
{
while ( threadIsStillRunning )
{
while ( !threadShouldExecute )
{
//Sleep the thread
}
//Execute the request
}
}
EDIT:
Ok, well here's the thread (this is contained in one of my class objects-WebServiceHelper):
private Thread executeRequest = new Thread()
{
public void run()
{
//Meat of the code
isRunning = false;
}
}
I then have another class method in the same class(WebServiceHelper):
private volatile boolean isRunning = false;
public void Execute(WebServiceHandler handler)
{
while ( isRunning )
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
isRunning = true;
r = handler;
executeRequest.start();
}
where r is just an interface object that I use to perform callbacks to the object performing the request.
Then in my main activity (the one that requested the thread execution i have this:
private Runnable getSiteData = new Runnable(){
public void run(){
mWebServiceHelper.SetMethod("GetSiteData");
mWebServiceHelper.Execute(mySiteHelper);
}
};
public void downloadDidFinish(List<Map<String, String>> data)
{
// TODO Auto-generated method stub
TeamList.StoreTeams(data );
mHandler.post(getSiteData);
}
downloadDidFinish gets called by the thread above upon completion, I then perform another request right after as you can see. The crash is happening when I try to call Execute again on the WebServiceHelper and start the thread again.
Asynctask is very useful to manage your threads.
https://developer.android.com/reference/android/os/AsyncTask.html
https://developer.android.com/resources/articles/painless-threading.html
Here is an example: http://labs.makemachine.net/2010/05/android-asynctask-example/
Is it possible for a background thread to enqueue a message to the main UI thread's handler and block until that message has been serviced?
The context for this is that I would like my remote service to service each published operation off its main UI thread, instead of the threadpool thread from which it received the IPC request.
This should do what you need. It uses notify() and wait() with a known object to make this method synchronous in nature. Anything inside of run() will run on the UI thread and will return control to doSomething() once finished. This will of course put the calling thread to sleep.
public void doSomething(MyObject thing) {
String sync = "";
class DoInBackground implements Runnable {
MyObject thing;
String sync;
public DoInBackground(MyObject thing, String sync) {
this.thing = thing;
this.sync = sync;
}
#Override
public void run() {
synchronized (sync) {
methodToDoSomething(thing); //does in background
sync.notify(); // alerts previous thread to wake
}
}
}
DoInBackground down = new DoInBackground(thing, sync);
synchronized (sync) {
try {
Activity activity = getFromSomewhere();
activity.runOnUiThread(down);
sync.wait(); //Blocks until task is completed
} catch (InterruptedException e) {
Log.e("PlaylistControl", "Error in up vote", e);
}
}
}