博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA线程异常终止
阅读量:6273 次
发布时间:2019-06-22

本文共 5336 字,大约阅读时间需要 17 分钟。

hot3.png

我们开发工程中经常使用到线程,在线程使用上,我们可能会有这样的场景:

  1. 伴随这一个业务产生一个比较耗时的任务,而这个业务返回并不需要等待该任务。那我们往往会启动一个线程去完成这个异步任务。

  2. 我们需要一个定时任务比如:定时清除数据,我们会起一个定时执行线程去做该任务。   

上述问题比较简单,new一个线程然后去做这件事。但是我们常常忽略一个问题,线程异常了怎么办? 比如耗时任务我们只完成了一半,我们就异常结束了(这里不考虑事务一致性,我们只考虑一定要将任务完成)。又比如在清数据的时候,数据库发生断连。这时候我们会发现线程死掉了,任务终止了,我们需要重启整个项目把该定时任务起起来。

场景一解决思路:

package cn.merryyou.thread;/** * Created by 11 on 2017/7/5. */public class Plan {    private SimpleTask task = new SimpleTask();    public static void main(String[] args) {        Plan plan = new Plan();        plan.start();    }    public void start(){        Thread thread = new Thread(task);        thread.setUncaughtExceptionHandler((t, e) -> {            System.out.println(e.getMessage());            start();        });        thread.start();    }    static class SimpleTask implements Runnable{        private int task = 10;        [@Override](https://my.oschina.net/u/1162528)        public void run() {            String threadName = Thread.currentThread().getName();            System.out.println(threadName+"--"+"启动");            while(task>0){                try {                    Thread.sleep(100);                }catch (InterruptedException e){                    e.printStackTrace();                }                if(System.currentTimeMillis()%3==0){                    throw new RuntimeException("模拟异常");                }                System.out.println(threadName+"--"+"执行task"+task);                task--;            }            System.out.println(threadName+"--"+"正常终止");        }    }}

输出:

Thread-0--启动Thread-0--执行task10Thread-0--执行task9Thread-0--执行task8模拟异常Thread-1--启动Thread-1--执行task7模拟异常Thread-2--启动模拟异常Thread-3--启动Thread-3--执行task6模拟异常Thread-4--启动Thread-4--执行task5模拟异常Thread-5--启动Thread-5--执行task4模拟异常Thread-6--启动Thread-6--执行task3模拟异常Thread-7--启动Thread-7--执行task2Thread-7--执行task1Thread-7--正常终止

线程池实现的方式:

package cn.merryyou.thread;import sun.java2d.pipe.SpanShapeRenderer;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadFactory;/** * Created by 11 on 2017/7/5. */public class Plan2 {    private Plan.SimpleTask task = new Plan.SimpleTask();    private MyFactory factory = new MyFactory(task);    public static void main(String[] args) {        Plan2 plan2 = new Plan2();        ExecutorService pool = Executors.newSingleThreadExecutor(plan2.factory);        pool.execute(plan2.task);        pool.shutdown();    }    class MyFactory implements ThreadFactory {        private Plan.SimpleTask task;        public MyFactory(Plan.SimpleTask task) {            super();            this.task = task;        }        [@Override](https://my.oschina.net/u/1162528)        public Thread newThread(Runnable r) {            Thread thread = new Thread(r);            thread.setUncaughtExceptionHandler((t, e) -> {                ExecutorService pool = Executors.newSingleThreadExecutor(new MyFactory(task));                pool.execute(task);                pool.shutdown();            });            return thread;        }    }}

输出:

Thread-0--启动Thread-0--执行task10Thread-1--启动Thread-1--执行task9Thread-1--执行task8Thread-1--执行task7Thread-2--启动Thread-2--执行task6Thread-3--启动Thread-3--执行task5Thread-3--执行task4Thread-3--执行task3Thread-3--执行task2Thread-3--执行task1Thread-3--正常终止

定时任务ScheduledExecutorService 实现方式:

package cn.merryyou.thread;import java.util.concurrent.*;/** * Created by 11 on 2017/7/5. */public class Plan3 {    private SimpleTask task = new SimpleTask();    public static void main(String[] args) {        Plan3 plan = new Plan3();        start(plan.task);    }    public static void start(SimpleTask task){        ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();        ScheduledFuture
future = pool.scheduleAtFixedRate(task, 0, 1000, TimeUnit.MILLISECONDS); try { future.get(); }catch (InterruptedException | ExecutionException e){ System.out.println(e.getMessage()); start(task); }finally { pool.shutdown(); } } class SimpleTask implements Runnable{ private volatile int count = 0; [@Override](https://my.oschina.net/u/1162528) public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName+"--启动"); try{ Thread.sleep(100); }catch (InterruptedException e){ e.printStackTrace(); } if(System.currentTimeMillis()%3==0){ throw new RuntimeException("模拟异常"); } System.out.println(threadName+"--执行task"+count); count++; System.out.println(threadName+"--正常终止"); } }}

输出:

pool-1-thread-1--启动pool-1-thread-1--执行task0pool-1-thread-1--正常终止pool-1-thread-1--启动java.lang.RuntimeException: 模拟异常pool-2-thread-1--启动java.lang.RuntimeException: 模拟异常pool-3-thread-1--启动java.lang.RuntimeException: 模拟异常pool-4-thread-1--启动java.lang.RuntimeException: 模拟异常pool-5-thread-1--启动java.lang.RuntimeException: 模拟异常pool-6-thread-1--启动java.lang.RuntimeException: 模拟异常pool-7-thread-1--启动java.lang.RuntimeException: 模拟异常pool-8-thread-1--启动pool-8-thread-1--执行task1pool-8-thread-1--正常终止pool-8-thread-1--启动pool-8-thread-1--执行task2pool-8-thread-1--正常终止pool-8-thread-1--启动......

参考链接:

转载于:https://my.oschina.net/merryyou/blog/1186284

你可能感兴趣的文章
oracle PL/SQL 流程控制
查看>>
Linux下/proc目录简介
查看>>
jenkins自动同步配置文件
查看>>
Windows系统清理 只需做到五大方面
查看>>
我的友情链接
查看>>
sql server 2005 (select查询语句用法)
查看>>
Spring整合Hibernate(1)
查看>>
3月7日作业
查看>>
python学习笔记(五)
查看>>
hebernate template 分页查询
查看>>
python开发之路SocketServer
查看>>
ARP Changes in Server 2008/Vista
查看>>
Linux主机安全笔记
查看>>
java 发送get和post请求
查看>>
动态加载JS,并执行回调函数
查看>>
go语言使用go-sciter创建桌面应用(七) view对象常用方法,文件选择,窗口弹出,请求...
查看>>
【翻译】优化基于ExtJS 4.1的应用
查看>>
ORACLE内存管理 之一 ORACLE PGA(转载)
查看>>
nmcli 使用记录---fatt
查看>>
我的友情链接
查看>>