文章目录
thinking in java 课后答案
Terminating task
Terminating when blocked
- New: A thread remains in this state only momentarily, as it is being created. It allocates any necessary system resources and performs initialization. At this point it becomes eligible to receive CPU time. The scheduler will then transition this thread to the runnable or blocked state.
- Runnable: This means that a thread can be run when the time-slicing mechanism has CPU cycles available for the thread. Thus, the thread might or might not be running at any moment, but there’s nothing to prevent it from being run if the scheduler can arrange it. That is, it’s not dead or blocked.
- Blocked: The thread can be run, but something prevents it. While a thread is in the blocked state, the scheduler will simply skip it and not give it any CPU time. Until a thread reenters the runnable state, it won’t perform any operations.
- Dead: A thread in the dead or terminated state is no longer schedulable and will not receive any CPU time. Its task is completed, and it is no longer runnable. One way for a task to die is by returning from its run( ) method, but a task’s thread can also be interrupted, as you’ll see shortly.
线程共有四种状态,New(刚初始化好,可执行)/Runnable(执行中)/Blocked(被某种原因阻塞,等待信号返回执行态)/Dead(任务执行完毕。从run()中返回和被打断都会使线程死亡)
Becoming blocked
- You’ve put the task to sleep by calling sleep(milliseconds), in which case it will not be run for the specified time.
- You’ve suspended the execution of the thread with wait( ). It will not become runnable again until the thread gets the notify( ) or notifyAll( ) message (or the equivalent signal( ) or signalAll( ) for the Java SE5 java.util.concurrent library tools). We’ll examine these in a later section.
- The task is waiting for some I/O to complete.
- The task is trying to call a synchronized method on another object, and that object’s lock is not available because it has already been acquired by another task
有四种线程陷入blocked的情况:
1、使用sleep();
2、wait(),此方法需要调用notify()、signal()函数才能唤醒;
3、等待I/O操作;
4、在调用其他对象的synchronized函数时被阻塞
The problem we need to look at now is this:Sometimes you want to terminate a task that is in a blocked state. If you can’t wait for it to get to a point in the code where it can check a state value and decide to terminate on its own, you have to force the task out of its blocked state.
我们聚焦:当不想等待任务自动从blocked退出时,强制退出blocked状态的方法
Interruption
抛出异常可以使线程跳出run(),但是在catch中需要注意清理所以相关资源
So that you can terminate a blocked task, the Thread class contains the interrupt( ) method. This sets the interrupted status for that thread. A thread with its interrupted status set will throw an InterruptedException if it is already blocked or if it attempts a blocking operation. The interrupted status will be reset when the exception is thrown or if the task calls Thread.interrupted( ). As you’ll see, Thread.interrupted( ) provides a second way to leave your run( ) loop, without throwing an exception.
调用interrupt()必须要有一个Thread对象,但是concurrency library 推荐使用Executors 而不是 Thread。在executor中调用shutdownNow()将会对每个启动的线程发送interrupt()指令,所有任务即将终止。
然而我们有时候只需要打断其中一个任务,此时我们使用submit(THREAD)函数替代execute(),此函数返回一个Future类,此类包含一个cancel(TRUE/FALSE)方法,可以打断此任务。
However, there are times when you may want to only interrupt a single task. If you’re using Executors, you can hold on to the context of a task when you start it by calling submit( ) instead of execute( ). submit( ) returns a generic Future<?>, with an unspecified parameter because you won’t ever call get( ) on it the point of holding this kind of Future is that you can call cancel( ) on it and thus use it to interrupt a particular task. If you pass true to cancel( ), it has permission to call interrupt( ) on that thread in order to stop it; thus cancel( ) is a way to interrupt individual threads started with an Executor.
import java.util.concurrent.*;
import java.io.*;
import static net.mindview.util.Print.*;
class SleepBlocked implements Runnable {
public void run() {
try {
TimeUnit.SECONDS.sleep(100);
} catch(InterruptedException e) {
print("InterruptedException in SleepBlocked");
}
print("Exiting SleepBlocked.run()");
}
}
class IOBlocked implements Runnable {
private InputStream in;
public IOBlocked(InputStream is) {
in = is; }
public void run() {
try {
print("Waiting for read():");
in.read();
} catch(IOException e) {
if(Thread.currentThread().isInterrupted()) {
print("Interrupted from blocked I/O");
} else {
throw new RuntimeException(e);
}
}
print("Exiting IOBlocked.run()