just a little question, i want to stiop the following thread, but i have no idea how i should do. Please help me. Googles help wasnt useful this time.
new Thread(){
public void run() {
while(!isInterrupted()){
try {
if (sock1!=null){
sock1.setTcpNoDelay(true);
if (btsar1.length > 0) {
dos1 = new DataOutputStream(sock1.getOutputStream());
bwrtr1 = new BufferedWriter(new OutputStreamWriter(
dos1), 300);
dos1.write(btsar1);
set1free = false;
Log.e("Communication", "written(1.1)");
Reader1.reader(4);}
}} catch (IOException e) {
e.printStackTrace();
}catch (NullPointerException e2){
e2.printStackTrace();
}
}
}}.start();
//.interrupt(); <-- or kinda that...
Can someone provide a good working thing, to stop this?
You just need a reference to your thread:
Thread t = new Thread(...);
Then you can interrupt it:
t.interrupt();
Thread t = new Thread(){
... // content unchanged
};
t.start();
.....
t.interrupt();
The best way to terminate a thread is to let it finish. So add a boolean flag in your while, and have method (or otherwise) expose it so it can be set to false. Then your thread would naturally exit after the interation has finished.
An idea: stop using anonymous threads!
Whenever you find yourself in a situation where your thread is doing something complicated, either create a separate class extending the thread, which can be used to control and monitor the behaviour, or use an abstract Future and a ThreadPool to do the work.
You will have an extremely unmaintainable and unextendable code if you keep using threads like this.
How to stop a thread gracefully?
bool keepWorking = true;
while(keepWorking) {
// keep working
}
synchronized void stopWork() {
keepWorking = false;
}
// in other thread
threadObj.stopWork();
Thread.interrupt method is for to stop a thread that waits for long periods (e.g., for input)
Take a look at this Article - How to Stop a Thread or a Task
example
public void stop() {
Thread moribund = waiter;
waiter = null;
moribund.interrupt();
}
Related
Recently I am working on a piece of code involving synchronization and struggling on how to test it. To get into the problem, we can consider we are writing a unit test for a CountDownLatch:
CountDownLatch l = new CountDownLatch(1);
new Thread() {
#Override
void run() {
l.await();
System.out.println("good!");
}
}.start();
Thread.sleep(1000); // wait for thread to run
if (the thread is alive)
l.countDown();
else
System.out.println("bad!");
So the problem is, there is no guarantee that the sleep for 1 second would be enough in all cases in all machines. So my goal is to eliminate this type of sleeping code to expect a certain state when testing synchronization, but soon realize it starts to become halting problem.
My current solution would be to query the state of the thread:
Thread t = ...
t.start();
if (t.getState() == Thread.State.WAITING) {
l.countDown();
assert(t.getState() == Thread.State.RUNNABLE); // or running or terminated
}
my questions are:
would that work? i.e. would the state of the thread will be toggled atomically at the moment, in this case, a count down latch reach a wakeup condition?(the doc says nothing about the change timing of the state)
do you have better suggestions?
Looking into your example I have a feeling that you're using countdown latch upside-down. Why can't you do something like that:
#Test
public void testThreads() throws Exception {
CountDownLatch l = new CountDownLatch(1);
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Parallel thread is doing something.");
try {
// instead of this sleep you put your logic that you want to be executed.
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
l.countDown();
}
}).start();
System.out.println("Main thread is waiting for parallel thread");
l.await();
System.out.println("Done.");
}
Please, correct me if I misunderstand your problem.
But generally speaking, I agree with one of the comments below your post that you should probably not test multithreading with unit tests.
I'm trying to write a code which wants to make a write thread. When I want to run it, I got this exception. Each post that I saw about this topic didn't have the code same as mine. So can any one help me about my problem?
java.lang.IllegalMonitorStateException
The stacktrace is as below:
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at prj.McWThread.ReadPacket(McWThread.java:40)
at prj.McWThread.run(McWThread.java:73)
The part of code that makes this exception is :
public void run()
{
try{
while (true)
{
this.MyPkt = ReadPacket();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(MyPkt);
}
}
}
Readpacket method:
public MyPacket ReadPacket()
{
MyPacket m = new MyPacket();
System.out.println("ReadPacket");
try {
while (Buff.isEmpty()) {
wait();
}
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
if (! Buff.isEmpty()) {
m = (MyPacket) Buff.remove(0);
return m;
} else {
return m;
}
}
You need to synchonize your call to wait in your code. Two Options:
Declare your method as syncronised
public syncronized MyPacket ReadPacket()
use synchronized(this) before your call to wait.
The first one may not be advisable depending on your design and the work other threads need to carry out, if any.
For the second option, again, you need to be sure if you would want to use this as your monitor. You can create a Lock and use that instead.
The javadoc for Object.wait.
"The current thread must own this object's monitor." and "[throws] IllegalMonitorStateException - if the current thread is not the owner of the object's monitor."
You need to synchronize on the object you are going to call the wait on.
The code should look something like
synchronize(someobject){
someobject.wait();
}
I am starting two thread one after the other.
The first thread is reading in a loop from input and the other one check some condition in a loop to
sent an interrupt to the other.
The problem is that any thread of the two I start first it doesnt let the other stop.
If i start reading in never runs the other thread until it finishes and if I start the other thread is checking the condition in the loop and it wont move forward in code until the condition is true and gets out of the loop.
What is the correct way to do it?
Sample code below:
Thread 1)
public class InterruptionThread extends Thread {
public void run() {
while (condition not true) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (condition true) {
do some work
return;
}
}
}
Thread 2)
public class ReadingThread extends Thread{
public void run() {
int input;
while (true) {
try {
input = stdInput.read();
} catch (IOException e) {
e.printStackTrace();
return;
}
System.out.print((char) input);
}
}
}
This sounds like you are not starting the threads in a correct manner.
Use the start() method to start threads, not the run() method (which doesn't actually start a thread).
new InterruptionThread().start();
new ReadingThread().start();
I think your problem is of producer consumer problem type.
So would suggest you to use BlockingQueue.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
Also instead of directly handling threads; it will be easy if you use Executor Framework; this way thread management will become pretty easy.
Started several worker threads , need to notify them to stop. Since some of the threads will sleep for a while before next round of working, need a way which can notify them even when they are sleeping.
If it was Windows programming I could use Event and wait functions. In Java I am doing this by using a CountDownLatch object which count is 1. It works but don't feel elegant, especially I have to check the count value to see if need to exit :
run(){
while(countDownLatch.count()>0){
//working
// ...
countDownLatch.wait(60,TimeUnit.SECONDS);
}
}
Semaphore is another choice, but also don't feel very right. I am wondering is there any better way to do this? Thank you.
Best approach is to interrupt() the worker thread.
Thread t = new Thread(new Runnable(){
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
//do stuff
try{
Thread.sleep(TIME_TO_SLEEP);
}catch(InterruptedException e){
Thread.currentThread().interrupt(); //propagate interrupt
}
}
}
});
t.start();
And as long as you have a reference to t, all that is required to "stop" t is to invoke t.interrupt().
Use the builtin thread interruption framework. To stop a worker thread call workerThread.interrupt() this will cause certain methods (like Thread.sleep()) to throw an interrupted exception. If your threads don't call interruptable methods then you need to check the interrupted status.
In the worker thread:
run() {
try {
while(true) {
//do some work
Thread.sleep(60000);
}
}
catch(InterruptedException e) {
//told to stop working
}
}
Good way is to interrupt() threads, and inside thread make cycle like
try {
while (!Thread.interrupted()) {
...
}
} catch (InterruptedException e) {
// if interrupted in sleep
}
Keep in mind both cases when do interrupt:
if you sleep or wait then InterruptedException will be thrown;
in other cases interrupted flag will be set for the thread which you have to check yourself.
To have a pool of threads I would use the ExecutorService or a ScheduledExecutorService for delayed/periodic tasks.
When you want the workers to stop you can use
executorService.shutdown();
The other best approach would be to use interrupt( ) method.
E.g Here's how a thread uses this information to determine whether or not it should terminate :
public class TestAgain extends Thread {
// ...
// ...
public void run( ) {
while (!isInterrupted( )) {
// ...
}
}
}
I have created a threaded service the following way:
public class TCPClientService extends Service{
...
#Override
public void onCreate() {
...
Measurements = new LinkedList<String>();
enableDataSending();
}
#Override
public IBinder onBind(Intent intent) {
//TODO: Replace with service binding implementation
return null;
}
#Override
public void onLowMemory() {
Measurements.clear();
super.onLowMemory();
}
#Override
public void onDestroy() {
Measurements.clear();
super.onDestroy();
try {
SendDataThread.stop();
} catch(Exception e){
...
}
}
private Runnable backgrounSendData = new Runnable() {
public void run() {
doSendData();
}
};
private void enableDataSending() {
SendDataThread = new Thread(null, backgrounSendData, "send_data");
SendDataThread.start();
}
private void addMeasurementToQueue() {
if(Measurements.size() <= 100) {
String measurement = packData();
Measurements.add(measurement);
}
}
private void doSendData() {
while(true) {
try {
if(Measurements.isEmpty()) {
Thread.sleep(1000);
continue;
}
//Log.d("TCP", "C: Connecting...");
Socket socket = new Socket();
socket.setTcpNoDelay(true);
socket.connect(new InetSocketAddress(serverAddress, portNumber), 3000);
//socket.connect(new InetSocketAddress(serverAddress, portNumber));
if(!socket.isConnected()) {
throw new Exception("Server Unavailable!");
}
try {
//Log.d("TCP", "C: Sending: '" + message + "'");
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
String message = Measurements.remove();
out.println(message);
Thread.sleep(200);
Log.d("TCP", "C: Sent.");
Log.d("TCP", "C: Done.");
connectionAvailable = true;
} catch(Exception e) {
Log.e("TCP", "S: Error", e);
connectionAvailable = false;
} finally {
socket.close();
announceNetworkAvailability(connectionAvailable);
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
connectionAvailable = false;
announceNetworkAvailability(connectionAvailable);
}
}
}
...
}
After I close the application the phone works really slow and I guess it is due to thread termination failure.
Does anyone know what is the best way to terminate all threads before terminating the application?
Addendum: The Android framework provides many helpers for one-off work, background work, etc, which may be preferable over trying to roll your own thread in many instances. As mentioned in a below post, AsyncTask is a good starting point to look into. I encourage readers to look into the framework provisions first before even beginning to think about doing their own threading.
There are several problems in the code sample you posted I will address in order:
1) Thread.stop() has been deprecated for quite some time now, as it can leave dependent variables in inconsistent states in some circumstances. See this Sun answer page for more details (Edit: that link is now dead, see this page for why not to use Thread.stop()). A preferred method of stopping and starting a thread is as follows (assuming your thread will run somewhat indefinitely):
private volatile Thread runner;
public synchronized void startThread(){
if(runner == null){
runner = new Thread(this);
runner.start();
}
}
public synchronized void stopThread(){
if(runner != null){
Thread moribund = runner;
runner = null;
moribund.interrupt();
}
}
public void run(){
while(Thread.currentThread() == runner){
//do stuff which can be interrupted if necessary
}
}
This is just one example of how to stop a thread, but the takeaway is that you are responsible for exiting a thread just as you would any other method. Maintain a method of cross thread communcation (in this case a volatile variable, could also be through a mutex, etc) and within your thread logic, use that method of communication to check if you should early exit, cleanup, etc.
2) Your measurements list is accessed by multiple threads (the event thread and your user thread) at the same time without any synchronization. It looks like you don't have to roll your own synchronization, you can use a BlockingQueue.
3) You are creating a new Socket every iteration of your sending Thread. This is a rather heavyweight operation, and only really make sense if you expect measurements to be extremely infrequent (say one an hour or less). Either you want a persistent socket that is not recreated every loop of the thread, or you want a one shot runnable you can 'fire and forget' which creates a socket, sends all relevant data, and finishes. (A quick note about using a persistent Socket, socket methods which block, such as reading, cannot be interrupted by Thread.interrupt(), and so when you want to stop the thread, you must close the socket as well as calling interrupt)
4) There is little point in throwing your own exceptions from within a Thread unless you expect to catch it somewhere else. A better solution is to log the error and if it is irrecoverable, stop the thread. A thread can stop itself with code like (in the same context as above):
public void run(){
while(Thread.currentThread() == runner){
//do stuff which can be interrupted if necessary
if(/*fatal error*/){
stopThread();
return; //optional in this case since the loop will exit anyways
}
}
}
Finally, if you want to be sure a thread exits with the rest of your application, no matter what, a good technique is to call Thread.setDaemon(true) after creation and before you start the thread. This flags the thread as a daemon thread, meaning the VM will ensure that it is automatically destroyed if there are no non-daemon threads running (such as if your app quits).
Obeying best practices with regards to Threads should ensure that your app doesn't hang or slow down the phone, though they can be quite complex :)
Actually, you don't need the "runner" variable as described above, something like:
while (!interrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
break;
}
}
But generally, sitting in a Thread.sleep() loop is a really bad idea.
Look at the AsyncTask API in the new 1.5 API. It will probably solve your problem more elegantly than using a service. Your phone is getting slow because the service never shuts down - there's nothing that will cause the service to kill itself.