Note that there are some explanatory texts on larger screens.

plurals
  1. POMaster and slave threads should shutdown using ctrl+c
    text
    copied!<p>I'm writing a program where the Main class initializes and starts a master thread. This master thread starts <code>n</code> slave threads. The program should terminate using <code>Ctrl+C</code>. Master thread must stop slave threads and finally stop itself. I've read a lot about <code>addShutdownHook</code> and here is my simplified implementation:</p> <pre><code>package dictator; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { Master m = new Master(); m.start(); } } class Master extends Thread { List&lt;Slave&gt; slaveMonitor = new ArrayList&lt;Slave&gt;(); public Master() { for (int i = 0; i &lt; 4; i++) { Slave slaveThread = new Slave(); slaveMonitor.add(slaveThread); } Thread shutDown = new Thread() { @Override public void run() { try { System.out.format("%nShutting down threads...%n"); for (Slave s : slaveMonitor) { s.interrupt(); s.join(); } interrupt() } catch (InterruptedException ex) { ex.printStackTrace(); } } }; Runtime.getRuntime().addShutdownHook(shutDown); } @Override public void run() { for (Slave s : slaveMonitor) { s.start(); } while (true) { System.out.println(getName() + " - Master"); try { Thread.sleep(1000); } catch (InterruptedException ex) { System.out.println(getName() + " interrupted."); break; } } System.out.println(getName() + " exiting."); } } class Slave extends Thread { public Slave() {} @Override public void run() { while (true) { System.out.println(getName() + " - Slave"); try { Thread.sleep(1500); } catch (InterruptedException ex) { System.out.println(getName() + " interrupted."); break; } } } } </code></pre> <p>The <code>addShutdownHook</code> catches the signal and terminates all slaves threads, but I'm not seen the master thread exiting (lines <code>System.out.println(getName() + " interrupted.");</code> and <code>System.out.println(getName() + " exiting.");</code> in master's run body.</p> <p>Here is my terminal's output:</p> <pre><code>Thread-1 - Slave Thread-2 - Slave Thread-3 - Slave Thread-0 - Master Thread-4 - Slave Thread-0 - Master ^C Shutting down threads... Thread-1 interrupted. Thread-2 interrupted. Thread-3 interrupted. Thread-4 interrupted. </code></pre> <p>Shouldn’t I see the line following lines? <em>What I'm I doing wrong?</em></p> <pre><code>Thread-0 interrupted. Thread-0 exiting. </code></pre> <h2>Changed Master Thread</h2> <pre><code>class Master extends Thread { List&lt;Slave&gt; slaveMonitor = new ArrayList&lt;&gt;(); List&lt;Thread&gt; killList = new ArrayList&lt;&gt;(); public Master() { for (int i = 0; i &lt; 4; i++) { Slave slaveThread = new Slave(); slaveMonitor.add(slaveThread); } killList.add(this); Thread shutDown = new Thread() { @Override public void run() { try { killList.addAll(slaveMonitor); Collections.reverse(killList); System.out.format("%nShutting down threads...%n"); for (Thread t : killList) { t.interrupt(); t.join(); } } catch (InterruptedException ex) { ex.printStackTrace(); System.out.println("Interrupted shutdown process"); System.exit(1); } } }; Runtime.getRuntime().addShutdownHook(shutDown); } ... </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload