Thread类的使用

前言:
每一个类都有wait(),notify()的方法,简单理解这两个方法:
1、对象维护了一个等待队列list;
2、线程A中执行对象的wait方法,把线程A保存到list中;
3、线程B中执行对象的notify方法,从等待队列中取出线程A继续执行;

文中中断方法的使用方法摘抄至:https://www.cnblogs.com/onlywujun/p/3565082.html

有关Thread类的几个方法:

//此方法是当有线程在竞争资源的时候让出资源
public static native void yield();
//让线程进入睡眠,但是不会释放锁
public static native void sleep(long millis) throws InterruptedException;
//真正地开启一个线程
public synchronized void start();
//直接调用并不是实现多线程,重写该方法实现具体业务逻辑
public void run() ;
//join实现了线程的同步调用,即有顺序地调用线程,内部还是靠wait方法
public final void join() throws InterruptedException;
//中断线程,设置中断状态位为true,线程会不断检测,是否能中断线程还得看线程本身
public void interrupt() ;
//线程是否中断
private native boolean isInterrupted(boolean ClearInterrupted);

/*tips:如何中断线程?
    如果一个线程处于了阻塞状态(如线程调用了thread.sleep、thread.join、
    thread.wait、1.5中的condition.await、
    以及可中断的通道上的 I/O 操作方法后可进入阻塞状态),
    则在线程在检查中断标示时如果发现中断标示为true,
    则会在这些阻塞方法(sleep、join、wait、1.5中的condition.await
    及可中断的通道上的 I/O 操作方法)调用处抛出InterruptedException异常,
    并且在抛出异常后立即将线程的中断标示位清除,即重新设置为false。
    抛出异常是为了线程从阻塞状态醒过来,并在结束线程前让程序员有足够的时间来处理中断请求。

注,synchronized在获锁的过程中是不能被中断的,意思是说如果产生了死锁,
则不可能被中断。与synchronized功能相似的reentrantLock.lock()方法也是一样,
    它也不可中断的,即如果发生死锁,那么reentrantLock.lock()方法无法终止,
    如果调用时被阻塞,则它一直阻塞到它获取到锁为止。但是如果调用带超时的
    tryLock方法reentrantLock.tryLock(long timeout, TimeUnit unit),
    那么如果线程在等待时被中断,将抛出一个InterruptedException异常,
    这是一个非常有用的特性,因为它允许程序打破死锁。
    你也可以调用reentrantLock.lockInterruptibly()方法,
    它就相当于一个超时设为无限的tryLock方法。

     没有任何语言方面的需求一个被中断的线程应该终止。
     中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断。
     某些线程非常重要,以至于它们应该不理会中断,而是在处理完抛出的异常之后继续执行,
     但是更普遍的情况是,一个线程将把中断看作一个终止请求,这种线程的run方法遵循如下形式:*/
public void run() {
    try {
        ...
        /*
         * 不管循环里是否调用过线程阻塞的方法如sleep、join、wait,这里还是需要加上
         * !Thread.currentThread().isInterrupted()条件,虽然抛出异常后退出了循环,显
         * 得用阻塞的情况下是多余的,但如果调用了阻塞方法但没有阻塞时,这样会更安全、更及时。
         */
        while (!Thread.currentThread().isInterrupted()&& more work to do) {
            do more work 
        }
    } catch (InterruptedException e) {
        //线程在wait或sleep期间被中断了
    } finally {
        //线程结束前做一些清理工作
    }
}
//另一种形式:
public void run() {
    while (!Thread.currentThread().isInterrupted()&& more work to do) {
        try {
            ...
            sleep(delay);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();//重新设置中断标示
        }
    }
}
//注意:不要在代码底层处理InterruptedException,eg:
void mySubTask(){
    ...
    try{
        sleep(delay);
    }catch(InterruptedException e){}//不要这样做
    ...
}
/*如果你不知道抛InterruptedException异常后如何处理,那么你有如下好的建议处理方式:
1、在catch子句中,调用Thread.currentThread.interrupt()来设置中断状态(因为抛出异常后中断标示会被清除),
让外界通过判断Thread.currentThread().isInterrupted()标示来决定是否终止线程还是继续下去,应该这样做:*/
void mySubTask() {
    ...
    try {
        sleep(delay);
    } catch (InterruptedException e) {
        Thread.currentThread().isInterrupted();
    }
    ...
}
//2、或者,更好的做法就是,不使用try来捕获这样的异常,让方法直接抛出:
void mySubTask() throws InterruptedException {
    ...
    sleep(delay);
    ...
}

/*中断应用
使用中断信号量中断非阻塞状态的线程

中断线程最好的,最受推荐的方式是,使用共享变量(shared variable)发出信号,告诉线程必须停止正在运行的任务。
线程必须周期性的核查这一变量,然后有秩序地中止任务。Example2描述了这一方式:*/
class Example2 extends Thread {
    volatile boolean stop = false;// 线程中断信号量

    public static void main(String args[]) throws Exception {
        Example2 thread = new Example2();
        System.out.println("Starting thread...");
        thread.start();
        Thread.sleep(3000);
        System.out.println("Asking thread to stop...");
        // 设置中断信号量
        thread.stop = true;
        Thread.sleep(3000);
        System.out.println("Stopping application...");
    }

    public void run() {
        // 每隔一秒检测一下中断信号量
        while (!stop) {
            System.out.println("Thread is running...");
            long time = System.currentTimeMillis();
            /*
             * 使用while循环模拟 sleep 方法,这里不要使用sleep,否则在阻塞时会 抛
             * InterruptedException异常而退出循环,这样while检测stop条件就不会执行,
             * 失去了意义。
             */
            while ((System.currentTimeMillis() - time < 1000)) {}
        }
        System.out.println("Thread exiting under request...");
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值