Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在方法调用之前中断阻塞方法_Java_Multithreading_Interrupt_Race Condition - Fatal编程技术网

Java 在方法调用之前中断阻塞方法

Java 在方法调用之前中断阻塞方法,java,multithreading,interrupt,race-condition,Java,Multithreading,Interrupt,Race Condition,我正在读这本书,(O'Reillys Java Threads第三版,目前有非常糟糕的解释),我遇到了以下代码: //in RandomCharacterGenerator class public void run( ) { while (!isInterrupted()) { nextCharacter( ); try { Thread.sleep(getPauseTime( ));

我正在读这本书,(O'Reillys Java Threads第三版,目前有非常糟糕的解释),我遇到了以下代码:

//in RandomCharacterGenerator class
public void run( ) {
    while (!isInterrupted()) {
            nextCharacter( );
            try {

                Thread.sleep(getPauseTime( ));

            } catch (InterruptedException ie) {
                return;
            }
    }
}
下面的解释(生产者是主线中上层阶级的实例):

如果主线程在RandomCharacterGenerator线程睡眠时执行此语句,则RandomCharacterGenerator线程将获得中断的异常,并立即从run()方法返回。否则,当字符馈送线程下一步到达其循环的顶部时,它会看到已设置中断标志,并从其run()方法返回。无论哪种方式,随机字符生成器线程都会完成其任务

请注意,这种技术并不能完全消除在线程被要求停止后我们睡眠一段时间的可能性。在RandomCharacterGenerator调用isInterrupted()方法之后,主线程可以调用interrupt()方法。字符读取线程仍然执行sleep()方法,该方法不会被中断(因为主线程已经完成了interrupt()方法)。这是我们在下一章中解决的竞争条件的另一个例子。由于这种情况下的竞争条件是良性的(这只是意味着我们比我们想要的多睡一次),这就足够了

第二段对我来说完全不清楚。我的第一个问题是:我们怎样才能多睡一个周期?如果我们在睡眠时中断线程,它将停止运行,如果我们在睡眠前中断,它将在它开始睡眠时中断睡眠(我测试过,我认为这是真的?我说的对吗),如果我们在睡眠后中断,它将停止循环


第二个问题:在本例中(这是本书中的全部代码),签入循环是否完全没有必要,并且它是否可以在(true)具有相同结果时保持不变,因此关于循环顶部的第一段完全是胡说八道?

本书是错误的。在线程睡眠之前中断线程将使sleep()方法立即抛出InterruptedException

引用Java并发的实践:

考虑中断的一个好方法是,它实际上并不中断正在运行的线程;它只是请求线程在下一个方便的时机中断自身。(这些机会被称为取消点。)一些方法,如等待、睡眠和加入,会认真对待这些请求,当它们收到中断请求或在进入时遇到已设置的中断状态时抛出异常

(强调矿山)


在这个特定的示例中,使用
while(true)
将产生相同的效果。但在其他情况下,如果循环从未调用可中断方法,或者如果您希望尽快退出,则必须定期检查线程是否被中断,以便能够检测到中断。

本书认为,在以下情况下,您将花费额外的周期:

RandomCharacterGenerator -> isInterrupted = false;

Main -> interrupt()

RandomCharacterGenerator -> runs through code
RandomCharacterGenerator -> sleeps
RandomCharacterGenerator -> isInterrupted = true

实际上,它会在睡眠时中断,但它试图获得的重要信息是,在调用interrupt()之后,您可以再次运行代码。

我认为此示例不使用Thread.interrupt,而是使用自定义布尔中断标志。所以producer.interrupt()只是将这个布尔标志设置为true,但不会中断休眠线程。不,它不会,前面的例子是设置标志,这个例子使用thread.interrupt,producer扩展线程,并且不会覆盖interruptk,如果是这样的话,那么您是对的。线程中断将导致休眠线程(或多或少)立即抛出InterruptedException。没有竞争条件。@croraf您可能会发现
Java并发在实践中更方便。泰·维克托,我会试试这个好答案!好书!Ty你最后的评论与Oracle在线教程中提到的概念相同,但这本书让我感到困惑,更重要的是我不是英语母语人士。我会查一下推荐书。我认为作者相信詹姆斯·拉格所说的是真的,但事实并非如此。我错了,书也错了。我刚刚尝试了这个实验,如果设置了标志,Thread.sleep()会立即抛出。这表明每个人在预测并发线程的结果时都必须非常小心:)
RandomCharacterGenerator -> isInterrupted = false;

Main -> interrupt()

RandomCharacterGenerator -> runs through code
RandomCharacterGenerator -> sleeps
RandomCharacterGenerator -> isInterrupted = true