Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Java concurrency guidelines.pdf
Скачиваний:
17
Добавлен:
23.05.2015
Размер:
1.35 Mб
Скачать

TPS01-J

prevent thread-starvation deadlock if the tasks were to block for some other reason, such as network I/O. Furthermore, because SynchronousQueue does not store tasks indefinitely for future execution, there is no unbounded queue growth, and all tasks are handled by the current thread or a thread in the thread pool.

This compliant solution is subject to the vagaries of the thread scheduler, which may not schedule the tasks optimally. However, it avoids thread-starvation deadlock.

5.2.5Risk Assessment

Executing interdependent tasks in a thread pool can lead to denial of service.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

TPS01- J

low

probable

medium

P4

L3

5.2.6References

[Gafter 2006]

A Thread Pool Puzzler

[Goetz 2006]

Section 8.3.2, “Managing queued tasks”

 

Section 8.3.3, “Saturation Policies”

 

Section 5.3.3, “Deques and work stealing”

[Sun 2009b]

 

CMU/SEI-2010-TR-015 | 131

TPS02-J

5.3TPS02-J. Ensure that tasks submitted to a thread pool are interruptible

Do not submit tasks that do not support interruption using Thread.interrupt() to a thread pool if it is necessary to shut down the thread pool or cancel individual tasks within it.

According to the Java API interface [Sun 2009b], the java.util.concurrent.ExecutorService.shutdownNow() method

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 besteffort 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.

Similarly, when attempting to cancel individual tasks within the thread pool using the Future.cancel() method, ensure that the tasks support interruption.

5.3.1Noncompliant Code Example (Shutting Down Thread Pools)

This noncompliant code example submits the SocketReader class as a task to the thread pool declared in PoolService.

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 {

CMU/SEI-2010-TR-015 | 132

TPS02-J

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();

}

}

Because the task does not support interruption using the Thread.interrupt() method, there is no guarantee that the shutdownNow() method will shut down the thread pool. Using the latter does not fix the problem either because it waits until all the executing tasks have finished.

Similarly, tasks that use some mechanism other than Thread.interrupted() to determine when to shut down will be unresponsive to shutdown() or shutdownNow(). For instance, tasks that check a volatile flag to determine whether it is safe to shut down will be unresponsive to these methods. The guideline “THI05-J. Do not use Thread.stop() to terminate threads” on page 110 provides more information on using a flag to terminate threads.

5.3.2Compliant Solution (Submit Interruptible Tasks)

This compliant solution defines an interruptible version of the SocketReader class, which is instantiated and submitted to the thread pool.

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));

CMU/SEI-2010-TR-015 | 133

TPS02-J

}

@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 { // ...

}

5.3.3Exceptions

TPS02-EX1: Short-running tasks that execute without blocking are not required to adhere to this guideline.

5.3.4Risk Assessment

Submitting tasks that are not interruptible may preclude the thread pool from shutting down and cause denial of service.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

TPS02- J

low

probable

medium

P4

L3

5.3.5References

[Goetz 2006]

Chapter 7, “Cancellation and shutdown”

[Sun 2009b]

Interface ExecutorService

CMU/SEI-2010-TR-015 | 134

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]