java多线程读书笔记3 介绍两种停掉线程的方法(停止线程的两种方法)

以上内容均来自于本书和我的自己理解的总结

Java Threads, 3rd Edition [Book] (oreilly.com)

第一种方法设置一个标识变量

1 Setting a Flag

The most common way of stopping a thread is to set some internal flag to signal that the thread should stop. The thread can then periodically query that flag to determine if it should exit.

停止线程最常见的方法是设置一些内部标志来表示线程应该停止。然后,线程可以定期查询该标志,以确定是否应该退出 (不断检查标志变量,如果符合判断停止的条件就正常执行并自然结束线程run方法)

public class Test extends Thread implements BusinessListener{

    ...

    private volatile boolean done = false;

    ...

    public void run( ) {

        while (!done) {

            ...

               }

    }

    public void setDone( ) {

        done = true;

    }

}

 在这里,我们创建了布尔标志done变量,以通知线程它应该退出。现在,run()方法不再会永远循环而不停止了,而是在每个循环中检查该done变量的状态,并在设置完done标志后返回。这终止了线程

Here we've created the boolean flag done to signal the thread that it should quit. Now instead of looping forever, the run() method examines the state of that variable on every loop and returns when the done flag has been set. That terminates the thread

 这就引出了一个有趣的设计问题:创建这样的新线程是更好的选择,还是挂起现有线程并在准备好后恢复它更好?当然,我们还没有必要的工具来编程线程的暂停和恢复,所以这就是我们这样做的原因。更自然的做法是暂停并恢复线程

This raises an interesting design question: is it better to create a new thread like this, or would it be better somehow to suspend the existing thread and resume it when we're ready? Of course, we don't yet have the tools necessary to program the suspension and resumption of the thread, so that's the reason we've done it this way. It would be more natural simply to suspend and resume the thread 

然而,在这种情况下,这其实并不重要。根据我们的经验,开发人员对他们认为创建线程会带来的性能损失过于关注。如果你正在编写一个程序,放弃一个线程并创建一个新线程比重用一个现有线程更容易,在大多数情况下,这是你应该做的 

However, in a case like this, it actually does not matter. In our experience, developers become too hung up on the perceived performance penalties they attribute to creating a thread. If you're writing a program and it is easier to abandon a thread and create a new one rather than reusing an existing one, in most cases that's what you should do. 

调用setDone()(上面提到过的信号变量)方法是线程之间进行通信的一种简单方法。线程必须使用特殊的通信规则(自定义特殊的通信规则)。不过,一般来说,线程可以相互调用方法,也可以访问相同的对象,以便在它们之间(线程之间)传递信息。 

Calling the setDone() method is a simple way for threads to communicate with each other. Threads must use special rules for communication .In general, though, threads can call methods on each other, as well as accessing the same objects, to pass information between themselves.

第二种方法:

Interrupting a Thread

中断一个线程

 在安排线程终止时,某种形式的延迟是不可避免的,但有时需要最小化延迟

知识点:blocking method(可阻塞式的方法)

In other cases, the delay can be worse: if the thread is executing a read() method to obtain data from a socket, the data may never come. Or the thread may be executing the wait() method and waiting for an event that may never come. Methods like these are called blocking methods because they block execution of the thread until something happens (e.g., the expiration of the sleep() method).

在其他情况下,延迟可能更严重:如果线程正在执行read()方法从套接字获取数据,数据可能永远不会出现。或者线程可能正在执行wait()方法并等待一个可能永远不会发生的事件。像这样的方法被称为阻塞方法,因为它们会阻塞线程的执行,直到发生某些事情(例如,sleep()方法过期,睡完了)。 

When you arrange for a thread to terminate, you often want it to complete its blocking method immediately: you don't want to wait for the data (or whatever) anymore because the thread is going to exit anyway. You can use the interrupt() method of the Thread class to interrupt any blocking method 

当你安排一个线程终止时,你通常希望它立即完成它的阻塞方法:你不想再等待数据(或任何东西),因为线程无论如何都会退出。可以使用Thread类的interrupt()方法中断任何阻塞方法 

The interrupt() method has two effects. First, it causes any blocked method to throw an InterruptedException. In our example, the sleep() method is a blocking method. If the event-processing thread interrupts the  thread while that thread is executing the sleep() method, the sleep method immediately wakes up and throws an InterruptedException. Other methods that behave this way include the wait() method, the join() method, and methods that read I/O  

interrupt()方法有两个效果。首先,它会导致任何被阻止的方法抛出InterruptedException。在我们的示例中,sleep()方法是一种阻塞方法。如果事件处理线程在该线程执行sleep()方法时中断该线程,sleep方法将立即唤醒并抛出InterruptedException。其他以这种方式运行的方法包括wait()方法、join()方法和读取I/O的方法

The second effect is to set a flag inside the thread object that indicates the thread has been interrupted. To query this flag, use the isInterrupted() method. That method returns true if the thread has been interrupted (even if it was not blocked). 

第二个效果是在thread对象内设置一个标志,指示线程已被中断。要查询此标志,请使用isInterrupted()方法。如果线程被中断(即使未被阻塞),该方法返回true。 

举个例子:样例代码:

public class Test extends Thread {

   



    public void run( ) {

        while (!isInterrupted( )) {//判断本线程是否被中断了

            ...

        }

    }

}

 This example is almost exactly the same as the one in which we use a done flag to signal that the thread should return. In this case, we use the interrupted flag instead. That means we no longer need the setDone() method. Instead of calling the setDone() method, the actionPerformed( ) method associated with the Stop button in our application now does this:

producer.interrupt( );

这个例子与我们使用done标志来表示线程应该返回的例子几乎完全相同。在本例中,我们使用中断标志。这意味着我们不再需要setDone()方法。与应用程序中的Stop按钮关联的actionPerformed()方法现在执行以下操作,而不是调用setDone()方法: 

producer.interrupt( );

第一种
设定标记

启发用的代码

pulic class MyThread extends Thread {

private volatile boolean doneSignal = false;

public void run(){
while(!doneSignal){

System.out.println("线程运行中....");


}

}


public void setDoneSignal(){//通过该方法来设定标记号值(用于判断线程是否一直执行循环体部分代码)

this.doneSignal=true;

}


}


第二种
中断Thread

例如如下一种情况:(36页)
当你在安排终结一个thread的时候,通常会想立即完成该线程的线程体内的一个阻塞方法(blocking method)因为你要使你的thread结束了,所以不再需要其线程体内的block method(阻断式)的方法(阻断方法)需要再等待什么了(不需要再等待数据或是其他的什么东西或事件发了)。此时调用Thread class的interrupt()方法可以用来中断线程体内的任何的blocking method(具有阻断性质方法)即 Thread 类的interrupt()方法可以中断线程体内的任何的blocking method从而使线程体内抛出InterruptedException类型的异常。
此interrupt()方法会产生两个效应:
(1)它会导致任何的blocked method抛出InterruptedException。
例如sleep()方法就是一个具有blocking method(阻断性质)的方法,如果处理时间的thread在执行sleep()方法的时候被中断了(利用interrupt()方法实现中断),那么此sleep()(阻断方法)会被立刻唤醒并抛出一个InterruptedException类型的异常对象。和sleep()方法类似的具有阻断性质的方法(blocking method)还有wait(),join()以及读取I/O的method等,他们都是具有阻断性质的方法即(blocking method)
(2)interrupt()方法引发的第二个效应是被interrupt(中断)的那个thread对象的内部的一个标记属性会指示该thread已经被中断。可以使用该thread对象的isInterrupted()方法来查询这个标记,此时被中断的thread对象的isInterrupted()方法会返回true.(注意就算该线程的线程体内(run方法方法体内)没有blocking method(阻断性质的方法),
被interrupt(中断)的那个thread对象的isInterrupted()方法也会返回true)

——————————————————————————————————————
注意:当要安排thread终结的时候出现小幅度延迟现象是无可避免的,但是有时候所开发的应用程序要求尽可能将这样的延迟缩减到最小。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值