Java并发学习笔记(4)线程的取消,关闭和异常终止

来源:互联网 发布:梦幻西游源码em 编辑:程序博客网 时间:2024/04/27 23:52

首先,要说的是java中没有一种停止线程的方法是绝对安全的.

线程的中断

Thread.interrput()方法很容易给人一种误会,让人感觉是一个线程使另外一个正在运行的线程停止工作,但实际上interrput仅仅传递了请求中断的信息.线程自己会在下一个方便的时间中断.某些操作会接受这个请求时发出一个异常,比如wait,sleep.每一个Thread线程都有一个中断状态,是boolean型的当调用interrput方法后会使中断为true.当使用的静态的interrputed时可以清除中断状态,也就是说连续调用2次interrputed会将中断状态变为false.isInterrupted方法可以返回中断状态.有时候调用interrput方法会出现异常而且中断状态没有改变,你可以在异常处理catch块中使用interrupted=true重试.

Java中断线程的时候分两种情况:第一种是在线程正常执行时,第二种是在线程阻塞时.

(1) 正常线程运行时一般会运行一个较长的任务有的会在while(true)中,这种线程最好中断只需要在循环中加入一个if(){break};判断就好.while判断条件是中断状态.嘿.

(2)在线程阻塞的时候进程不会执行其他任何命令,所以不能改变判断状态.这时候使用Thread.interrupt()方法产生一个InterruptedException运行时异常,在catch块中,跑出一个运行时异常(RuntimeException)或使用break;这种方法可以适用于{ Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中阻塞的线程,能看出来这些方法都会跑出InterruptedException异常}

            try {                TimeUnit.SECONDS.sleep(1);            } catch (InterruptedException e) {//              break;                thrownew RuntimeException();            }

(3)你不可以中断试图获取synchronized锁但是由于锁被占用未被释放而被挂起的线程或者试图执行I/O操作的线程.

a)  对于IO异常

i.  对于被I/O读写阻塞的线程嘴简单直接的方法是调用基础资源的close()方法.也就是读写的close方法.(旧IO不会发出InterruptedException异常但是使用close方法会跑出IOException异常同上使用相同方法可以跳出循环中断线程)

ii. 在新版本的nio类会自动响应中断,发出IOException异常

b) 对于由于互斥堵塞.使用ReentrantLock对象加锁的线程可以被终结,使用ReentrantLock的lockInterruptibly方法,如果当前线程未被中断,则获取锁这就可以中断被互斥的锁。

c)处理反常的线程终止

在并发程序中,发生异常而未能捕获异常这使得线程执行失败,但是往往这种失败,不会影响程序的继续执行.导致失败的主要原因还是RuntimeException这种异,通常这种异常是不能捕获的.如何捕获这些异常呢.?javaAPI提供了这一类问题的解决办法,提供了Thread.UncaughtExceptionHandler(异常处理器具体查看JDK)使你能够检测到线程因未捕获而引起的线程死亡.可以使用Thread的set方法设置异常处理器.如果不存在异常处理器则使用System.err输出.PS:在运行时间较长时间的线程里,为线程提供一个异常处理器是有必要的,至少在这个处理器中记录日志.为了给线程池中的每个线程都加入异常处理器,可以在建造线程池的时候给定一个ThreadFactory.为每个线程池内的Thread加入异常处理器.PS.线程池只有通过execute方法才会将异常交给异常处理器.通过submit方式提交的会使用get方法重新给出异常.使用异常处理器后不会使用system.err向控制台写入异常.

原创粉丝点击