JAVA多线程中的中断机制。主要是stop方法、interrupted()与isInterrupted()方法的区别

JAVA中有3种方式可以终止正在运行的线程

①线程正常退出,即run()方法执行完毕了

②使用Thread类中的stop()方法强行终止线程。但stop()方法已经过期了,不推荐使用

③使用中断机制

 

在java的Thread类中,调用Thread.stop();源码可以看出

/**
 * Forces the thread to stop executing.
 * <p>
 * If there is a security manager installed, its <code>checkAccess</code>
 * method is called with <code>this</code>
 * as its argument. This may result in a
 * <code>SecurityException</code> being raised (in the current thread).
 * <p>
 * If this thread is different from the current thread (that is, the current
 * thread is trying to stop a thread other than itself), the
 * security manager's <code>checkPermission</code> method (with a
 * <code>RuntimePermission("stopThread")</code> argument) is called in
 * addition.
 * Again, this may result in throwing a
 * <code>SecurityException</code> (in the current thread).
 * <p>
 * The thread represented by this thread is forced to stop whatever
 * it is doing abnormally and to throw a newly created
 * <code>ThreadDeath</code> object as an exception.
 * <p>
 * It is permitted to stop a thread that has not yet been started.
 * If the thread is eventually started, it immediately terminates.
 * <p>
 * An application should not normally try to catch
 * <code>ThreadDeath</code> unless it must do some extraordinary
 * cleanup operation (note that the throwing of
 * <code>ThreadDeath</code> causes <code>finally</code> clauses of
 * <code>try</code> statements to be executed before the thread
 * officially dies).  If a <code>catch</code> clause catches a
 * <code>ThreadDeath</code> object, it is important to rethrow the
 * object so that the thread actually dies.
 * <p>
 * The top-level error handler that reacts to otherwise uncaught
 * exceptions does not print out a message or otherwise notify the
 * application if the uncaught exception is an instance of
 * <code>ThreadDeath</code>.
 *
 * @exception  SecurityException  if the current thread cannot
 *               modify this thread.
 * @see        #interrupt()
 * @see        #checkAccess()
 * @see        #run()
 * @see        #start()
 * @see        ThreadDeath
 * @see        ThreadGroup#uncaughtException(Thread,Throwable)
 * @see        SecurityManager#checkAccess(Thread)
 * @see        SecurityManager#checkPermission
 * @deprecated This method is inherently unsafe.  Stopping a thread with
 *       Thread.stop causes it to unlock all of the monitors that it
 *       has locked (as a natural consequence of the unchecked
 *       <code>ThreadDeath</code> exception propagating up the stack).  If
 *       any of the objects previously protected by these monitors were in
 *       an inconsistent state, the damaged objects become visible to
 *       other threads, potentially resulting in arbitrary behavior.  Many
 *       uses of <code>stop</code> should be replaced by code that simply
 *       modifies some variable to indicate that the target thread should
 *       stop running.  The target thread should check this variable
 *       regularly, and return from its run method in an orderly fashion
 *       if the variable indicates that it is to stop running.  If the
 *       target thread waits for long periods (on a condition variable,
 *       for example), the <code>interrupt</code> method should be used to
 *       interrupt the wait.
 *       For more information, see
 *       <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 */
@Deprecated
public final void stop() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        checkAccess();
        if (this != Thread.currentThread()) {
            security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
        }
    }
    // A zero status value corresponds to "NEW", it can't change to
    // not-NEW because we hold the lock.
    if (threadStatus != 0) {
        resume(); // Wake up thread if it was suspended; no-op otherwise
    }

    // The VM can handle all thread states
    stop0(new ThreadDeath());
}

强制线程停止的话,会抛出一个 java.lang.ThreadDeath 异常,但在通常情况下,此异常不需要显式的捕获

看下面列子

package cn.enjoyedu.ch1.base.test;

public class TestObject {



    private String username="cc";


    private String password="cccc";

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    synchronized public void printString(String username, String password) throws InterruptedException {
        this.username = username;
        Thread.sleep(10000);
        this.password = password;
    }
}


class MyThreadStop implements Runnable{


    private TestObject testObject=new TestObject();

    public MyThreadStop(TestObject testObject){
        this.testObject=testObject;
    }
    @Override
    public void run() {

        try {
            testObject.printString("ddd","dd");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

 

package cn.enjoyedu.ch1.base.test;

public class StopTestRun{

    public static void main(String[] aegs) throws InterruptedException {

        TestObject testObject=new TestObject();

        MyThreadStop myThreadStop=new MyThreadStop(testObject);


        Thread thread=new Thread(myThreadStop);
        thread.start();

        Thread.sleep(500);


        thread.stop();
        System.out.println(testObject.getPassword()+",,,"+testObject.getUsername());
    }

}

 

分析:
线程 MyThreadStop 执行完 this.username = username 后,此时username = b,password = aaa,调用 sleep() 方法让当前线程睡眠 10s,线程睡眠时,释放CPU资源,Main线程获取到CPU调度获取到时间片,Main线程继续往下执行,调用 stop() 方法,释放 thread 线程。printString() 方法不再往下执行

 

运行程序出现
cccc,,,ddd

 

使用 interrupt 方法停止线程

看下面的Thread类中的源码

/**
 * Tests whether this thread has been interrupted.  The <i>interrupted
 * status</i> of the thread is unaffected by this method.
 *
 * <p>A thread interruption ignored because a thread was not alive
 * at the time of the interrupt will be reflected by this method
 * returning false.
 *
 * @return  <code>true</code> if this thread has been interrupted;
 *          <code>false</code> otherwise.
 * @see     #interrupted()
 * @revised 6.0
 */
*测试此线程是否已中断。<我>中断

* status不受此方法的影响。

线程中断被忽略,因为一个线程不是活动的

*在中断的时候会被这个方法反射

*返回false。

* @return true如果这个线程已经被中断;

* @revised 6.0
public boolean isInterrupted() {
    return isInterrupted(false);
}

要通过使用 interrupt() 方法停止线程,需要先了解 Thread.interrupted 和 this.isInterrupted() 这两个方法。这两个方法的作用都是用于判断线程是否处于停止状态。
1)Thread.interrupted() 测试当前线程是否已经中断,执行后具有将状态标志置清除为 false 的功能。(Thread 类里的静态方法)
2)this.isInterrupted() 测试线程是否已经中断,但不清楚状态标志(标记位由ClearInterrupted决定)

/**
 * Tests if some Thread has been interrupted.  The interrupted state
 * is reset or not based on the value of ClearInterrupted that is
 * passed.
 */
private native boolean isInterrupted(boolean ClearInterrupted);

 isInterrupted是中断擦除

使用 interrupt() 和抛异常法停止线程
由于代码中出现过多的 return; 会造成对代码的污染,而使用抛异常的方法时,在catch 块中可以对异常的信息进行相关的处理,而且使用异常流能更好、更方便地控制程序的运行流程。实现与 return相似,把return; 处替换成 throw XxxException() 即可。
 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值