java - stopping threads that run indefinitely -
i have been trying implement producer consumer pattern. if both producer , consumer running indefinitely how should 1 try stop them?
i have been trying test status of isinterrupted()
following code not guarantee threads stop.
public class monitor { private int value; private boolean readable = false; public synchronized void setval(int value) { while (readable) { try { this.wait(); } catch (interruptedexception e) { break; } } if (!thread.currentthread().isinterrupted()) { this.readable = true; this.value = value; this.notifyall(); } } public synchronized int getval() { while (!readable) { try { this.wait(); } catch (interruptedexception e) { break; } } if (!thread.currentthread().isinterrupted()) { this.readable = false; this.notifyall(); } return this.value; } }
the producer class looks this:
import java.util.random; public class producer implements runnable { private monitor monitor; private random r = new random(); private string name; public producer(monitor m) {monitor = m;} public void run() { name = thread.currentthread().getname(); while (!thread.currentthread().isinterrupted()) { int value = r.nextint(1000); monitor.setval(value); system.out.println("producer: " + name + " set " + value); } system.out.println("producer: " + name + " interrupted"); } }
the consumer
public class consumer implements runnable { private monitor monitor; private string name; public consumer(monitor m) {monitor = m;} public void run() { name = thread.currentthread().getname(); while (!thread.currentthread().isinterrupted()) { int value = monitor.getval(); system.out.println("consumer: " + name + " got " + value); } system.out.println("consumer: " + name + " interrupted"); } }
and main:
public class main { public static void main(string[] args) { final int n = 2; monitor m = new monitor(); thread[] producers = new thread[n]; thread[] consumers = new thread[n]; (int = 0; < n; i++) { producers[i] = new thread(new producer(m)); producers[i].start(); consumers[i] = new thread(new consumer(m)); consumers[i].start(); } // try { // thread.sleep(1); // } catch (interruptedexception e) {} (int = 0; < n; i++) { producers[i].interrupt(); consumers[i].interrupt(); } } }
i following results
producer: thread-0 set 917 consumer: thread-1 got 917 producer: thread-2 set 901 producer: thread-0 set 29 consumer: thread-3 interrupted consumer: thread-1 got 29 consumer: thread-1 interrupted producer: thread-2 set 825 ...program hangs
and
producer: thread-0 set 663 consumer: thread-1 got 663 producer: thread-0 set 129 consumer: thread-1 got 129 producer: thread-2 set 93 producer: thread-2 interrupterd consumer: thread-3 interrupted producer: thread-0 set 189 producer: thread-0 interrupterd consumer: thread-1 got 129 ...program hangs
etc...
there wrong. why not registering calls interrupt
on consistent basis?
it perhaps surprising catching interruptedexception
does not mean interrupted flag set on thread.
the interrupted flag , interruptedexception
2 separate ways of indicating interrupt has occurred:
- you can throw
interruptedexception
without first checking whether thread has been interrupted. - you can set interrupted flag without catching
interruptedexception
.
in order correctly preserve fact thread interrupted (or, @ least, interruptedexception
caught), should explicitly re-interrupt thread in catch block:
// ... } catch (interruptedexception e) { thread.currentthread().interrupt(); break; } // ...
this sets interrupted flag, isinterrupted()
check should work.
Comments
Post a Comment