(15)Java多线程之线程异常

来源:互联网 发布:陈赫品牌淘宝店 编辑:程序博客网 时间:2024/05/17 01:35

  • 引言
  • Sleep相关的异常
    • 1 InterruptedException
  • wait相关的异常
    • 1 等待阶段调用中断方法异常
    • 2 调用wait方法却没有对象锁
    • 3 调用wait方法虽然是同步方法但是不是相应的对象锁
  • join相关的异常
    • 1 线程等待调用interrupt异常
  • 捕捉异常
    • 1给对象添加异常捕捉器
    • 2 给线程类添加异常捕捉器相当于给全部对象添加异常捕捉
    • 3 线程组内处理异常
    • 4 自定义异常

1.引言

      在本篇博客中主要记录一下:在多线程编程当中出现的异常,以及如何去捕捉异常。

2.Sleep相关的异常

2.1 InterruptedException

在这里我们首先要看一下Sleep中的InterruptedException异常是如何产生的。

  • 创建线程类
public class MyThread extends Thread {    public void run() {             try {            Thread.sleep(2000);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
  • 在线程sleep阶段调用interrupt()方法
public class App {    public static void main(String[] args) throws Exception {        MyThread td=new MyThread();        td.start();        //保证线程正在沉睡        Thread.sleep(1000);        td.interrupt();    }}
  • 产生异常

这里写图片描述

  • 异常原因
    当线程处于睡眠的情况下,不可以调用中断方法。

3.wait相关的异常

3.1 等待阶段调用中断方法异常

  • 线程类
public class MyThread extends Thread {    private  Object lock;    public MyThread(Object lock){        this.lock=lock;    }    public void run() {        synchronized (lock) {            try {                lock.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}
  • 线程等待阶段调用interrupt()方法
public class App {    public static void main(String[] args) throws Exception {        Object lock=new Object();        MyThread td=new MyThread(lock);        td.start();        Thread.sleep(1000);        td.interrupt();    }}
  • 运行异常

这里写图片描述

  • 异常原因
    当线程处于等待的情况下,不可以调用中断方法。

3.2 调用wait方法,却没有对象锁

  • 创建线程类
public class MyThread extends Thread {    private Object lock;    public MyThread(Object lock) {        this.lock = lock;    }    public void run() {        try {            lock.wait();        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
  • 运行线程类
public class App {    public static void main(String[] args) throws Exception {        Object lock=new Object();        MyThread td=new MyThread(lock);        td.start();    }}
  • 产生异常

这里写图片描述

  • 产生异常的原因
    运行lock.wait();方法的线程,没有获得lock对象锁,注意一定要获取lock对象锁

3.3 调用wait方法,虽然是同步方法,但是不是相应的对象锁

  • 线程类
public class MyThread extends Thread {    private Object lock1;    private Object lock2;    public MyThread(Object lock1,Object lock2) {        this.lock1 = lock1;        this.lock2=lock2;    }    public void run() {        synchronized (lock2) {            try {                lock1.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}
  • 运行线程类
public class App {    public static void main(String[] args) throws Exception {        Object lock1=new Object();        Object lock2=new Object();        MyThread td=new MyThread(lock1,lock2);        td.start();    }}
  • 出现异常

这里写图片描述

  • 异常原因
    线程虽然获得了lock2的对象锁,但是没有获得lock1的对象锁

4.join相关的异常

我们之前提过:join的底层是通过wait方法实现的。也就是说当线程处于join方法等待时,是不可以调用interrupt()方法

4.1 线程等待调用interrupt()异常

  • 创建线程类
public class MyThread extends Thread {    public void run() {        try {            this.join();        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
  • main方法
public class App {    public static void main(String[] args) throws Exception {        Object o=new Object();        MyThread td=new MyThread();        td.start();        Thread.sleep(1000);             td.interrupt();    }}
  • 出现异常

这里写图片描述

  • 异常产生的原因
    在线程等待的情况下调用了interrupt()方法

5.捕捉异常

      在多线程中如果出现了异常我们应该如何捕捉呢?比如我们的线程类是:

public class MyThread extends Thread {    public void run() {        String username=null;        //这里应该是空指针异常        System.out.println(username.trim());    }}

5.1给对象添加异常捕捉器

  • main方法
import java.lang.Thread.UncaughtExceptionHandler;public class App {    public static void main(String[] args) throws Exception {        MyThread td=new MyThread();        td.setName("异常线程");        td.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {                 public void uncaughtException(Thread t, Throwable e) {                System.out.println("出现异常的线程是:"+t.getName());                System.out.println(e.toString());            }        });        td.start();    }}
  • 运行结果

这里写图片描述

5.2 给线程类添加异常捕捉器(相当于给全部对象添加异常捕捉)

  • main方法
import java.lang.Thread.UncaughtExceptionHandler;public class App {    public static void main(String[] args) throws Exception {        MyThread td=new MyThread();        td.setName("异常线程");        MyThread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {            public void uncaughtException(Thread t, Throwable e) {                System.out.println("出现异常的线程是:"+t.getName());                System.out.println(e.toString());            }        });        td.start();    }}
  • 线程类

这里写图片描述

5.3 线程组内处理异常

      线程组中的异常我们实现的功能为:如果组内某一个线程出现了异常,那么线程组内的所有线程都要停止

  • 创建两个线程(线程A 有异常,线程B 无异常)
public class MyThreadA extends Thread {    public MyThreadA(ThreadGroup group) {        super(group,"MyThreadA");    }    public void run() {        String username=null;        //这里应该是空指针异常        System.out.println(username.trim());    }}
public class MyThreadB extends Thread {    public MyThreadB(ThreadGroup group) {        super(group,"MyThreadB");    }    public void run() {        while(!this.isInterrupted())        {            System.out.println("线程组没有异常");        }    }}
  • 自定义我们的线程组
public class MyThreadGroup extends ThreadGroup{    public MyThreadGroup(String name) {        super(name);    }    public void uncaughtException(Thread t, Throwable e) {        this.interrupt();        super.uncaughtException(t, e);    }}
  • main函数
import java.lang.Thread.UncaughtExceptionHandler;public class App {    public static void main(String[] args) throws Exception {        MyThreadGroup group=new MyThreadGroup("异常线程组");        MyThreadA tdA=new MyThreadA(group);        MyThreadB tdB=new MyThreadB(group);        tdA.start();        tdB.start();    }}
  • 运行结果(当线程组A出现异常之后,线程组B 也停止了。)

这里写图片描述

5.4 自定义异常

如果我们自定义我们的异常类型:实现UncaughtExceptionHandler接口

import java.lang.Thread.UncaughtExceptionHandler;public class ObjectUncaughtExceptionHandler  implements UncaughtExceptionHandler{    public void uncaughtException(Thread t, Throwable e) {        //在这里写我们的异常处理       }}
1 0
原创粉丝点击