Java 线程中断笔记

  1. 正常结束
  2. 全局变量中断
  3. interrupt
  4. stop (线程抛异常,释放所有锁)

interrupt (内容摘自网上)

一、中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断。
二、对于处于sleep,join等操作的线程,如果被调用interrupt()后,会抛出InterruptedException,然后线程的中断标志位会由true重置为false,因为线程为了处理异常已经重新处于就绪状态。
三、不可中断的操作,包括进入synchronized段以及Lock.lock(),inputSteam.read()等,调用interrupt()对于这几个问题无效,因为它们都不抛出中断异常。如果拿不到资源,它们会无限期阻塞下去。
对于Lock.lock(),可以改用Lock.lockInterruptibly(),可被中断的加锁操作,它可以抛出中断异常。等同于等待时间无限长的Lock.tryLock(long
time, TimeUnit unit)。
对于inputStream等资源,有些(实现了interruptibleChannel接口)可以通过close()方法将资源关闭,对应的阻塞也会被放开。

首先,看看Thread类里的几个方法:

public static boolean interrupted测试当前线程是否已经中断。线程的中断状态 由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false。
public boolean isInterrupted()测试线程是否已经中断。线程的中断状态 不受该方法的影响。
public void interrupt()中断线程。上面列出了与中断有关的几个方法及其行为,可以看到interrupt是中断线程。如果不了解Java的中断机制,这样的一种解释极容易造成误解,认为调用了线程的interrupt方法就一定会中断线程。

其实,Java的中断是一种协作机制。也就是说调用线程对象的interrupt方法并不一定就中断了正在运行的线程,它只是要求线程自己在合适的时机中断自己。每个线程都有一个boolean的中断状态(这个状态不在Thread的属性上),interrupt方法仅仅只是将该状态置为true。
比如对正常运行的线程调用interrupt()并不能终止他,只是改变了interrupt标示符。
一般说来,如果一个方法声明抛出InterruptedException,表示该方法是可中断的,比如wait,sleep,join,也就是说可中断方法会对interrupt调用做出响应(例如sleep响应interrupt的操作包括清除中断状态,抛出InterruptedException),异常都是由可中断方法自己抛出来的,并不是直接由interrupt方法直接引起的。
Object.wait, Thread.sleep方法,会不断的轮询监听 interrupted
标志位,发现其设置为true后,会停止阻塞并抛出 InterruptedException异常。

测试代码

package com;

import com.entity.Data;

import java.util.*;
import java.util.concurrent.*;


/**
 * interrupt()是给线程设置中断标志;
 * interrupted()是检测中断并清除中断状态;
 * isInterrupted()只检测中断。
 *
 * interrupted()作用于当前线程,interrupt()和isInterrupted()作用于此线程,

 */
public class ThreadTest {
    // 全局变量方式结束线程
    static volatile boolean exitFlag =  false;
    public static void main(String[] args) {
       // test1();
//        test2();
        test3();

    }
    // 全局变量方式结束线程
    public static void test1(){

        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                while (!exitFlag){
                    System.out.println(new Date().getTime());
                    try {
                        Thread.sleep(5*1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };



        Thread thread = new Thread(runnable1);
        thread.start();
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("输入t 结束线程");
            String df = sc.next();
            if ("t".equals(df)){
                exitFlag = true;
            }
        }
    }

    // interrupt 方式1结束线程  当线程处于阻塞时 调用 interrupt(中断) 方法抛异常 跳出结束线程
    public static void test2(){


        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println(new Date().getTime());
                    try {
                        Thread.sleep(5*1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break ;
                    }
                }
                System.out.println("线程执行完成");
            }
        };



        Thread thread = new Thread(runnable1);
        thread.start();
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("输入t 结束线程");
            String df = sc.next();
            if ("t".equals(df)){
                thread.interrupt();
            }
        }
    }

    // interrupt 方式2结束线程 (常用)
    public static void test3(){

        Thread thread = new MyThread();
        thread.start();
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("输入t 结束线程");
            String df = sc.next();
            if ("t".equals(df)){
                thread.interrupt();
            }else {
                thread.interrupted();
            }
        }
    }

    static class MyThread extends Thread{
        @Override
        public void run() {
            while (true){
                long time = System.currentTimeMillis();
                while ((System.currentTimeMillis() - time < 1000) ) {
                }
                if (!Thread.currentThread().isInterrupted()){
                    System.out.println(time);
                }else {
                    System.out.println("恢复中断");
                }
                // interrupted()作用于当前线程   恢复中断
                // System.out.println("...::" +  Thread.currentThread().interrupted());
            }

        }
    }


}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值