JAVA_线程中断与InterruptedException

2018-08-21  本文已影响0人  Shokka
什么是线程中断:

要有线程中断,则需要有线程等待为前提:
等待1.当线程调用了sleep,wait,join方法时,线程都会进入阻塞状,等待被notify
等待2.线程正在获取锁并等待,进入阻塞状的线程可以显示调用Thread.interrupt()方法,让thread线程响应中断,注意:只有lock锁可以响应中断,使用synchronized关键字不可以。

中断1.当等待1情况响应了中断时,会抛出InterruptedException异常,并进入catch块中,这个时候就等于在catch中重新获取了线程的主导权,而不是等回复运行态获取主导权,InterruptedException异常可以处理也可以不处理。
中断2.当等待2情况响应了中断,会不会抛出InterruptedException异常,例如tryLock(long time, TimeUnit unit)方法会停止等待并直接返回false。

中断2的demo:
提问:对于lock.tryLock的响应中断,可以用try catch块嵌套 if (lock.tryLock(4,TimeUnit.SECONDS)),也可以直接在方法体throws InterruptedException,哪种比较好呢,希望你都试一试,自己去理解。

package org.kevin.lucene;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {
    
    private static Lock lock = new ReentrantLock();
    
    
    public void test(Thread currentThread) throws InterruptedException{
        long now = System.currentTimeMillis();
        if (lock.tryLock(4,TimeUnit.SECONDS)) {
            try {
                
                System.out.println(currentThread.getName()+"获取锁");
                while(System.currentTimeMillis()-now < 10000) {
                
                }
                
            }
            finally {
                System.out.println(currentThread.getName()+"释放锁");
                lock.unlock();
                // TODO: handle finally clause
            }
        }else {
            System.out.println(currentThread.getName()+"放弃获取锁");
        }
        
    }
    
    
    public static void main(String[] args) {
        
        LockTest test = new LockTest();
        Thread t1 = new MyThread(test, "Thread--A");
        Thread t2 = new MyThread(test, "Thread--B");
        t1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t2.start();
        
        
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t2.interrupt();
        

    }

}
class MyThread extends Thread{

    private LockTest test;
    
    public MyThread(LockTest test,String threadName) {
        super(threadName);
        this.test = test;
        
    }
    
    public void run() {
        System.out.println(this.getName()+" -》 进入了run方法");
        try {
            test.test(this);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            System.out.println("捕获终止异常");
            e.printStackTrace();
        }
    }
}

如果用try catch块嵌套lock.tryLock(4,TimeUnit.SECONDS),则只能用两个try catch块

public void test(Thread currentThread){
        long now = System.currentTimeMillis();
        try {
            if (lock.tryLock(4,TimeUnit.SECONDS)) {
                try {
                    
                    System.out.println(currentThread.getName()+"获取锁");
                    while(System.currentTimeMillis()-now < 10000) {
                    
                    }
                    
                }
                finally {
                    System.out.println(currentThread.getName()+"释放锁");
                    lock.unlock();
                    // TODO: handle finally clause
                }
            }else {
                System.out.println(currentThread.getName()+"放弃获取锁");
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

如果只用一个try catch块,则会出现A线程获取了锁,B线程正在等待锁,但是B线程中断了之后依然在finally中释放了锁的情况,会直接报错,如下:

    public void test(Thread currentThread){
        long now = System.currentTimeMillis();
        try {
            if (lock.tryLock(4,TimeUnit.SECONDS)) {
                
                    System.out.println(currentThread.getName()+"获取锁");
                    while(System.currentTimeMillis()-now < 10000) {
                    
                    }
                    
                
                
            }else {
                System.out.println(currentThread.getName()+"放弃获取锁");
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            System.out.println(currentThread.getName()+"释放锁");
            lock.unlock();
            // TODO: handle finally clause
        }
        
    }
上一篇 下一篇

猜你喜欢

热点阅读