1

Could someone please tell me how to stop a thread if I have the following structure?

I want to stop the thread B after it expires thread C.

enter image description here

    c = new c();
    c.start();
    b = new b();
    b.start();

class c extends Thread {

    @Override
    public void run() {
      // DRAW IMAGE
      // b.stop(); - doenst work
    }
}

class b extends Thread {

    @Override
    public void run() {
      // PROGRESS BAR

    }
}
Adil Shaikh
  • 44,509
  • 17
  • 89
  • 111
  • 1
    You should implement the progress bar with a Swing Timer (or even a regular java.util.Timer) and then you won't have to resort to any hacks for stopping. – Marko Topolnik Mar 26 '14 at 09:01

9 Answers9

5

There is no good way to stop a thread instantly.

  • There is Thread.stop(), but it is dangerous and deprecated. Don't use it unless you have thoroughly analyzed your code and determined that the risks are acceptable.

  • There is Thread.interrupt(), but there is no guarantee that the thread will stop quickly, or even stop at all.

For Example:

while (!Thread.interrupted()) {
    try {
        //do stuff
    } catch (InterruptedException e) {
        // end up
    }
}
  • There is the approach of writing the thread to periodically check a flag, but if the flag is not checked frequently (by accident or by design), then the thread won't stop quickly.

Please Refer to this for more details

Community
  • 1
  • 1
Salah
  • 8,567
  • 3
  • 26
  • 43
  • 3
    This is a rather pessimistic answer. The OP seemingly has full control over the code of each thread, so your second or third bullet point is a perfectly practical solution for this problem. – Duncan Jones Mar 26 '14 at 09:07
  • You should show a code example of how to use `Thread.currentThread().isInterrupted()`. Yes, you may not check for it. Also, there are daemon threads. – fge Mar 26 '14 at 09:14
2

Don't use .stop() use interrupt() instead

You need to check periodically in your b thread if it gets interrupted, if interrupted , you can take proper actions -

if(b.isInterrupted()){
  //end your work
}

---> http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Adil Shaikh
  • 44,509
  • 17
  • 89
  • 111
2

Don't use Thread.stop() method, It's already deprecated, in this case you can handle the stopping of the b thread in your code.

For example:

class b extends Thread {
    private volatile boolean stopped = false;


    public void stop () {
        stopped = true;
    }

    @Override
    public void run() {
      // PROGRESS BAR
      while ( ! stopped ) {
         // paint the progress bar
      }

    }
}
s4m0k
  • 568
  • 1
  • 4
  • 12
1

You might want to take a look at this. You can use a flag or just use Thread.currentThread().interrupt(), you can check if a thread is interrupted by calling Thread.isInterrupted() on it.

Community
  • 1
  • 1
1

The solution to this is explained quite well here. Any thread that might need a status flag for shutdown could have the following structure:

volatile boolean shutdownRequested;

...

public void shutdown() { shutdownRequested = true; }

public void doWork() { 
    while (!shutdownRequested) { 
        // do stuff
    }
}

Thus, in your case, your class B would look similar to the above. And then, in class C, you can call the shutdown() method of class B.

Aritra
  • 1,234
  • 12
  • 20
0

create a lockable object in your calling code

Boolean canRun = true;
c = new c();

when b has finished set canRun to false

periodically check value of canRun in c

Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
0

Use a Boolean flag.

For Thread safety, use AtomicBoolean.

AtomicBoolean running = new AtomicBoolean(Boolean.TRUE);

In your run() method check this flag in a while condition:

public void run(){
    while(running){
    ...
    }
}

When you want to stop this Thread, change the running to false

isah
  • 5,221
  • 3
  • 26
  • 36
  • AtomicBoolean is overkill, a `volatile boolean` is perfectly enough. Also there is already the `interrupted` flag provided by the platform. – Marko Topolnik Mar 26 '14 at 09:02
  • What's so overkill about it? It's just a volatile variable inside an object. It sounds microoptimiziation to me. – isah Mar 26 '14 at 09:05
  • Explain what is wrong with a volatile variable. If you can't then it's overkill. Throwing around words like "microoptimization" to justify gratuitous overcomplication is nothing but the admittance to the weakness of your argument. – Marko Topolnik Mar 26 '14 at 09:07
  • I didn't say volatile is wrong, did I? Why don't you explain the overkill instead? I might learn from it. – isah Mar 26 '14 at 09:11
  • 1
    `volatile boolean` is simpler, it's a native language feature, it doesn't need method calls to set or get it, it's automatically initialized. But all these are so obvious that they really shouldn't require an explanation. AtomicBoolean was introduced for the specific use case of atomic CAS operations, which you do not intend to use. – Marko Topolnik Mar 26 '14 at 09:17
  • Yes right, fixed. Posted directly here. Yes these points are obvious and mostly they're about primitive vs Object, which from my experience, depends on application needs. So, it might be overkill a little, but obviously insignificant. – isah Mar 26 '14 at 09:28
  • Not at all insignificant. That kind of mentality to gratuitously involve features you don't need, in this case making the usage syntax more complicated, repeatedly applied at each step in the application design results in a horrible mess. Not that I haven't witnessed my fair share of such mess on real projects. – Marko Topolnik Mar 26 '14 at 09:33
  • In your edited code, writing `new AtomicBoolean(Boolean.TRUE)` is yet another example of the above. You involve a `Boolean` instance which will immediately be auto-unboxed to a primitive `boolean`. You really do seem to enjoy writing more code than needed. – Marko Topolnik Mar 26 '14 at 09:36
  • 1
    Sir, this is getting subjective. You prefer primitives, I don't, and never had any performance issues with using wrappers. Actually, I think non-primitives make code more clear(probably I'm used to it). And I don't think one should trade readability for micro optimization. But again I said, it depends on application needs. If your developing an application where hardware is limited and high performance is a must, then it makes sense. But I've heard people also use C! This discussion ends for me. – isah Mar 26 '14 at 09:46
  • You are misusing the term "microoptimization" which doesn't at all apply here. We are not discussing performance, but programming model. Applications needs are that the solution *works*, and it works with a `volatile boolean`, which is also the standard practice for this use case. You may prefer involving unnecessary APIs, but that just means that *your* personal, and peculiar, preference is designing with gratuitous overkill. – Marko Topolnik Mar 26 '14 at 09:48
  • If you are so enamored with objects against primitive types, then you should have used a `volatile Boolean` variable. There is absolutely no possible justification for an `AtomicBoolean`. – Marko Topolnik Mar 26 '14 at 09:50
  • I believe the problem with volatile variables in general is synchronization. Effective Java Item 66 talks about the additional precautions needed while using a volatile field. Probably, that's why people avoid them most of the time, and go for the safer option. – Aritra Mar 26 '14 at 18:04
0

Well, try this :

while(true) {
  if (!c.isAlive() && b.isAlive()){
      b.interrupt();
  }
}
Zied.Jabnoun
  • 140
  • 1
  • 2
  • 10
0

Try something like

 private void startActionPerformed(java.awt.event.ActionEvent evt) {

 p=new Progress();
 myThread=new Thread(p);
 p.setLocationRelativeTo(null);
 p.setVisible(true);
 myThread.start();

}

private void stopActionPerformed(java.awt.event.ActionEvent evt) {

  if(myThread!=null){
  p.Terminate();
  try {
  myThread.join();
  } catch (InterruptedException ex) {
 Logger.getLogger(ClassA.class.getName()).log(Level.SEVERE, null, ex);
   }
   }

   }

////////////////////////////////////////////////////////////////

How it Works and Stopped!

    int i;
    volatile boolean running=true;
    public void run(){
          while(running){
      for(i=0;i<=100;i++){
    pro.setValue(i);
     try {
     Thread.sleep(200);
     } catch (InterruptedException ex) {
     Logger.getLogger(Progress.class.getName()).log(Level.SEVERE, null, ex);
    return;
    }
   if(i==100){
     Terminate();
    break;
    }
   }
 }

}

public void Terminate(){ running=false; }

/////////////////////////////////////////////////////////////////////

Tech Nerd
  • 822
  • 1
  • 13
  • 39