Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Wiki Markup
Programs may submit _only_ tasks that support interruption using {{Thread.interrupt()}} to thread pools that require the ability to shut down the thread pool or to cancel individual tasks within the pool. Programs must not submit tasks that lack interruption support to such thread pools. According to the Java API interface \[[API 2006|AA. Bibliography#API 06]\], the {{java.util.concurrent.ExecutorService.shutdownNow()}} method

Attempts attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution. There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.

...

Code Block
bgColor#FFcccc
public final class SocketReader implements Runnable { // Thread-safe class
  private final Socket socket;
  private final BufferedReader in;
  private final Object lock = new Object();

  public SocketReader(String host, int port) throws IOException {
    this.socket = new Socket(host, port);
    this.in = new BufferedReader(
        new InputStreamReader(this.socket.getInputStream())
    );
  }

  // Only one thread can use the socket at a particular time
  @Override public void run() {
    try {
      synchronized (lock) {
        readData();
      }
    } catch (IOException ie) {
      // Forward to handler
    }
  }

  public void readData() throws IOException {
    String string;
    try {
      while ((string = in.readLine()) != null) {
        // Blocks until end of stream (null)
      }
    } finally {
      shutdown();
    }
  }

  public void shutdown() throws IOException {
    socket.close();
  }
}

public final class PoolService {
  private final ExecutorService pool;

  public PoolService(int poolSize) {
    pool = Executors.newFixedThreadPool(poolSize);
  }

  public void doSomething() throws InterruptedException, IOException {
    pool.submit(new SocketReader("somehost", 8080));
    // ...
    List<Runnable> awaitingTasks = pool.shutdownNow();
  }

  public static void main(String[] args) 
                          throws InterruptedException, IOException {
    PoolService service = new PoolService(5);
    service.doSomething();
  }
}

...

Code Block
bgColor#ccccff
public final class SocketReader implements Runnable {
  private final SocketChannel sc;
  private final Object lock = new Object();

  public SocketReader(String host, int port) throws IOException {
    sc = SocketChannel.open(new InetSocketAddress(host, port));
  }

  @Override public void run() {
    ByteBuffer buf = ByteBuffer.allocate(1024);
    try {
      synchronized (lock) {
        while (!Thread.interrupted()) {
          sc.read(buf);
          // ...
        }
      }
    } catch (IOException ie) {
      // Forward to handler
    }
  }
}

public final class PoolService {
  // ...
}

Exceptions

TPS02-EX0: Short-running tasks that execute without blocking are exempt from this rule.

...

Submitting tasks that are uninterruptible may prevent a thread pool from shutting down and consequently may cause denial of serviceDoS.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

TPS02-J

low

probable

medium

P4

L3

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8dbc6287002794b6-9f61b5c6-4bf24ef0-a28aa3d2-0ec77a4d97618988054d08bd"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

interface ExecutorService

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="f69e64d6e1f8a315-da099c39-49ee40fc-bc50827a-255a73b11bcd3b4c6783e466"><ac:plain-text-body><![CDATA[

[[Goetz 2006

AA. Bibliography#Goetz 06]]

Chapter 7: , Cancellation and shutdown Shutdown

]]></ac:plain-text-body></ac:structured-macro>

...