5

したがって、私がこれを正しく理解していれば、スレッドはオブジェクトで待機を呼び出すと待機状態になり、オブジェクトのロックを待機しているときにブロック状態になります(同期ブロックまたはメソッドに入ろうとするときなど) )。

read() のような I/O メソッドはどのようにしてスレッドをブロック状態にしますか? ブロックされた状態で読み取り可能なデータを待機しなければならない理由は理解していますが、その方法にも興味があります。JVM は、読み取ろうとしているリソース内のデータが再び使用可能になったときに、続行できることをスレッドにどのように通知しますか?

4

2 に答える 2

7

スレッドの状態を BLOCKED に変更しません。

public static void main(String[] args) throws IOException {
    Thread main = Thread.currentThread();
    new Thread(() -> {
        for (int i = 0; i < 10; i++) {
            System.out.println(main + " is in "+main.getState()+" state");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new AssertionError(e);
            }
        }
    }).start();
    System.in.read();
}

版画

Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state

read代わりに、OSは何らかのデータが存在し、OS がスレッド/プロセスをコンテキスト スイッチするかどうか、およびそのタイミングを決定するまで、から戻りません。

JVM は、読み取ろうとしているリソース内のデータが再び使用可能になったときに、続行できることをスレッドにどのように通知しますか?

OS は、さらにデータがあるか、ストリームが閉じられると、スレッドを起こします。JVM は関与しません。

于 2016-12-14T12:36:14.080 に答える
0

これは、ネイティブ プラットフォームによって異なります。

POSIX では、read通常、データが利用可能になるまで への呼び出しはブロックされますが、ファイルの終わりに達した、ファイル記述子が閉じられた、操作がタイムアウトした、操作が信号によって中断されたなど、他にも多くの理由で返されます。

Windows で最も関連性の高い関数はReadFile.


Java 8 更新 112 b15 を参照して、悲惨な詳細:

FileInputStream.readJava_java_io_FileInputStream_read0の JNI を介してネイティブFileInputStream.read0に実装されたネイティブを呼び出します。readSingleIO_Read

POSIX では、IO_Readは として定義されておりhandleRead、これは を呼び出しますread。エラーが発生している間、RESTARTABLEマクロはループします。errnoEINTR

Windows では、IO_Readは として定義されhandleRead、これは を呼び出しますReadFile

于 2016-12-14T12:13:14.520 に答える