简体   繁体   中英

Java thread doesn't stop/interrupt

I'm trying to terminate a thread but it doesn't interrupt or stop. All of this are part of controller of a software called Webots. I use this to simulate a multi robot system. In the controller of each robot, I start a thread which receive messages through robots receivers. This thread must start at first, and terminate when simulation ends.

The run method for this thread look like this:

public void run() {
    while (true)
    {
        String M = recieveMessage();
        char[] chars = M.toCharArray();
        if(chars[0]==robotName||chars[0]=='0')
            messages.add(M);                                                
     }
}

In the main controller I have code that look like this:

MessageThread MT = new MessageThread(messages, receiver,getName());
MT.start();
for (int i = 0; i < 100; i++)
{
    try
    {
         Thread.sleep(25);  } catch (InterruptedException e) {      e.printStackTrace();    }
    System.out.println(messages.get(messages.size()-1));                
 }
 MT.interrupt();//MT = null;
 System.out.println(MT.interrupted());

It's not important what I do in my main controller, so don't judge it. For example, messages is an ArrayList. It's like a buffer which MT put messages in and the main thread reads from. I use it because the receiver and emitter are not synchronized.

If I call interrupt() or MT = null but interrupted() it returns false and MT continues to run. Is there anything wrong in my code?

I read some topics like:

http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

How do you kill a Thread in Java?

interrupt() doesn't work

Java: How interrupt/stop a thread?

and so on but I couldn't find any useful answer.

Edit

Thanks everyone, I've made changes to my code. I added this to the MessageThread class:

private volatile boolean isRunning = true;

Then I used while(isRunning) instead of while(true) and I added

public void kill()
{
    isRunning = false;
}

and called MT.kill() instead of MT.interrupt() .

It worked but I couldn't find out what's wrong with interrupt(). I read the link which @ExtremeCoders recommended. However, I'm still confused. It says "a thread must support its own interruption". So do I have to overwrite the interrupt() method? I can't call interrupt to terminate a thread?

Thanks again.

Interrupting a thread just sets a flag on the thread. If the thread never checks the flag, it won't respond. By creating your own boolean member, you've duplicated that functionality unnecessarily.

Here's the general pattern for what you are trying to do:

@Override
public void run() {
  while(!Thread.interrupted() {
    /* Do something. */
  }
  Thread.currentThread().interrupt();
}

This will allow you to call MT.interrupt() as you expected. It's better than creating your own flag and custom method to set it: you can use your Runnable task with high-level tools like ExecutorService and cancellation will work because you used the standard API; same is true for interruption of an entire ThreadGroup .

Calling Thread.interrupted() clears the interruption status of a thread; we set it by calling Thread.currentThread().interrupt() , the status is set again so that callers of run() can detect the interrupted state. This might not always be desirable however.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM