线程异常处理

线程异常处理

异常处理方法:

1.直接在子线程内try-catch,不能通知到主线程
2.不在子线程内try-catch,新建MyUncaughtExceptionHandler 实现Thread.UncaughtExceptionHandler,重写uncaughtException(Thread t, Throwable e) 处理异常,不能通知到主线程
3.线程任务实现Callable接口,FutureTask包裹线程任务,可在主线程中处理线程异常
4. Executors.callable 可在主线程中处理线程异常
5.Executors.new…()生产ExecutorService executorService ,executorService 调用submit(new MyTask())产生Future实例,可在主线程中处理线程异常

一、主线程try-catch不能捕获子线程的异常

public class ThreadSon {
    public static void main(String[] args) {
        Thread thread = null;
        try {
            thread = new Thread(new MyTask());
        } catch (Exception e) {
            System.out.println("----主线程捕获异常: "+e.getMessage());
        }
        thread.start();
    }
    static class MyTask implements Runnable{
        @Override
        public void run() {
            try {
                System.out.println(1/0);
            } catch (Exception e) {
                System.out.println("----子线程捕获异常: "+e.getMessage());
            }
        }
    }
}

输出:
----子线程捕获异常: / by zero
Process finished with exit code 0

注:1.异常处理第一种办法:直接在子线程内try-catch,不能通知到主线程
2.JVM会调用 dispatchUncaughtException 来寻找handler进行处理。而如果没有自定义hanlder进行处理,则会调用 System.err 进行输出

    public void uncaughtException(Thread t, Throwable e) {
        if (parent != null) { // 父级优先处理
            parent.uncaughtException(t, e);
        } else {
            Thread.UncaughtExceptionHandler ueh =
                Thread.getDefaultUncaughtExceptionHandler();
            if (ueh != null) {
                ueh.uncaughtException(t, e);
            } else if (!(e instanceof ThreadDeath)) { // 没有配置handler时的处理方式
                System.err.print("Exception in thread \""
                                 + t.getName() + "\" ");
                e.printStackTrace(System.err);
            }
        }
    }

二、MyUncaughtExceptionHandler

package com.wx;

public class ThreadSon {
    public static void main(String[] args) {
        MyUncaughtExceptionHandler myUncaughtExceptionHandler = new MyUncaughtExceptionHandler();
        Thread thread = null;
        try {
            thread = new Thread(new MyTask());
            thread.setUncaughtExceptionHandler(myUncaughtExceptionHandler);
        } catch (Exception e) {
            System.out.println("----主线程捕获异常: "+e.getMessage());
        }
        thread.start();
    }
    static class MyTask implements Runnable{
        @Override
        public void run() {
            System.out.println(1/0);
        }
    }
    static class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.err.println("线程"+t.getName()+"捕获异常: " + e.getMessage());
        }
    }
}

输出:
线程Thread-0捕获异常: / by zero
Process finished with exit code 0

三、线程任务实现Callable接口,FutureTask包裹线程任务

package com.wx;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThreadSon2 {
    public static void main(String[] args) {
        FutureTask<String> stringFutureTask = new FutureTask<>(new MyTask());
        Thread thread = new Thread(stringFutureTask);
        thread.start();
        try {
            String s = stringFutureTask.get();
            System.out.println("stringFutureTask返回结果:"+s);
        } catch (InterruptedException e) {
            System.err.println("stringFutureTask捕获异常: " + e.getMessage());
        } catch (ExecutionException e) {
            System.err.println("stringFutureTask捕获异常: " + e.getMessage());
        }
    }

    static class MyTask implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println(1/1);
            return "succeed";
        }
    }
}

输出:
1
stringFutureTask返回结果:succeed
Process finished with exit code 0

如果在MyTask.call()中发送异常,比如:

package com.wx;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThreadSon2 {
    public static void main(String[] args) {
        FutureTask<String> stringFutureTask = new FutureTask<>(new MyTask());
        Thread thread = new Thread(stringFutureTask);
        thread.start();
        try {
            String s = stringFutureTask.get();
            System.out.println("stringFutureTask返回结果:"+s);
        } catch (InterruptedException e) {
            System.err.println("stringFutureTask捕获异常: " + e.getMessage());
        } catch (ExecutionException e) {
            System.err.println("stringFutureTask捕获异常: " + e.getMessage());
        }
    }

    static class MyTask implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println(1/0);
            return "succeed";
        }
    }
}

输出:
stringFutureTask捕获异常: java.lang.ArithmeticException: / by zero
Process finished with exit code 0

四、Executors.callable()

import java.util.concurrent.*;

public class ThreadSon3 {
    public static void main(String[] args) {
        String result = "";
        Callable<String> callable = Executors.callable(new MyTask(),result);
        try {
            callable.call();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    static class MyTask implements Runnable{
        @Override
        public void run() {
            System.out.println(1/0);
        }
    }
}
输出:
java.lang.ArithmeticException: / by zero
	at com.wx.ThreadSon3$MyTask.run(ThreadSon3.java:20)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at com.wx.ThreadSon3.main(ThreadSon3.java:10)
Process finished with exit code 0

五、Future

package com.wx;

import java.util.concurrent.*;

public class ThreadSon4 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Future<?> future = executorService.submit(new MyTask());
        try {
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            if (executorService!=null) {
                executorService.shutdown();
            }
        }
    }
    static class MyTask implements Runnable{
        @Override
        public void run() {
            System.out.println(1/0);
        }
    }
}

输出
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:192)
	at com.wx.ThreadSon4.main(ThreadSon4.java:10)
Caused by: java.lang.ArithmeticException: / by zero
	at com.wx.ThreadSon4$MyTask.run(ThreadSon4.java:26)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值