***


Javaのスレッドには、次の4つのステータスがあります.
1.新規(new):スレッドが作成されると、この状態は短くなるだけです.必要なシステムリソースが割り当てられ、初期化が実行されました.スレッドはCPU時間を取得する資格があり、スケジューラはこのスレッドを実行可能状態またはブロック状態に変更します.
2.準備(Runnable):この状態で、スケジューラがスレッドにタイムスライスを割り当てる限り、スレッドは実行できます.すなわち,任意の時点でスレッドを実行してもよいし,実行しなくてもよい.スケジューラがスレッドにタイムスライスを割り当てることができれば、実行できます.これは死と閉塞とは異なる.
3.ブロック(Blocked):スレッドは実行できますが、実行を阻止する条件があります.スレッドがブロックされている場合、スケジューラはスレッドを無視し、スレッドにCPU時間を割り当てません.スレッドが準備完了状態になるまで、操作を実行できません.
4.デッド(Dead):デッドまたはエンドのスレッドはスケジューリング不可能になり、CPU時間が得られなくなります.タスクの死亡の通常の方法はrun()メソッドから返されるが、タスクのスレッドは中断されることもある.
ブロック状態に入る理由:
1.sleep()でタスクをスリープ状態にし、指定した時間内にタスクが実行されません.
2.wait()でスレッドを停止します.スレッドがnotify()またはnotifyAll()メッセージを取得するまで、スレッドは準備完了状態になります.
3.タスクは入力出力の完了を待っています.
4.タスクは、あるオブジェクト上で同期制御方法を呼び出そうとしますが、別のスレッドがこのロックを取得しているため、オブジェクトロックは使用できません.
中断:
Threadクラスにはinterrupt()メソッドが含まれているため、ブロックされたタスクを終了することができます.
次の例では、基本的なinterrupt()の使い方をExecutorで示します.
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
 
class SleepBlocked implements Runnable{
     
    public void run() {
        try{
            TimeUnit.SECONDS.sleep(100);
        }catch(InterruptedException e){
            System.out.println("InterruptedException");
        }
        System.out.println("Exiting SleepBlocked.run()");
    }
}
 
class IOBlocked implements Runnable{
    private InputStream in;
    public IOBlocked (InputStream is){
        in=is;
    }
    public void run() {
        try {
            System.out.println("waiting for read()");
            in.read();
        } catch (IOException e) {
            if(Thread.currentThread().isInterrupted()){
                System.out.println("Interrupted from blocked I/O");
            }else{
                throw new RuntimeException();
            }
        }
        System.out.println("Exiting IOBlocked.run()");
    }
}
 
class SynchronizedBlocked implements Runnable{
    public synchronized void f(){
        while(true){//never releases lock
            Thread.yield();
        }
    }
    public SynchronizedBlocked(){
        new Thread(){
            public void run(){
                f();//lock acquired by this thread
            }
        }.start();
    }
    public void run() {
        System.out.println("Trying to call f()");
        f();
        System.out.println("Exiting SynchronizedBlocked.run()");
    }
     
}
 
public class Interrupting {
    private static ExecutorService exec = Executors.newCachedThreadPool();
    static void test(Runnable r) throws InterruptedException{
        Future<?> f = exec.submit(r);
        TimeUnit.MILLISECONDS.sleep(100);
        System.out.println("Interrupting "+r.getClass().getName());
        f.cancel(true);//Interrupts if running
        System.out.println("Interrupt sent to "+r.getClass().getName()+"
"); } public static void main(String args[]) throws Exception{ test(new SleepBlocked()); test(new IOBlocked(System.in)); test(new SynchronizedBlocked()); TimeUnit.SECONDS.sleep(3); System.out.println("Aborting with system.exit(0)"); System.exit(0); } }

この例の結果から,SleepBlockは中断可能であり,後者の2つの場合は中断できないことが分かる.