线程
一、五种状态
1.新建(new):线程对象被创建后的状态
2.就绪(runnable):当调用线程对象的start()方法,线程进入就绪状态
处于就绪状态的线程做好了被调用的准备
3.运行状态(running):cpu开始调度处于就绪状态的线程时,此时线程真正执行
注意:就绪状态是进入到运行状态的唯一入口。即线程要进入运行状态,首先必须处于就绪状态
4.阻塞状态(blocked):处于运行中的线程暂时放弃对cpu的使用权,停止执行,此时进入阻塞状态,直到其进入运行状态才有机会再次被cpu调用进入运行状态。根据阻塞的原因,可以分为三类:
等待阻塞:运行中的线程执行wait()方法;
同步阻塞:线程获取synchronize同步锁失败(被其它线程占用);
其它阻塞:调用线程的sleep()或join()或发出了i/o请求时进入阻塞,sleep或join超时、i/o处理完毕后重新进入就绪状态
5.死亡状态(dead):线程执行完毕或异常退出了run()方法,该线程结束生命周期
二.线程状态转换
1.调用join()、sleep()方法;sleep()时间结束或被打断;join()中断;io完成:均会将线程改为就绪(runnable)状态,等待调度
2.调用wait():使该线程处于等待池,直到notify()/notifyall(),线程被唤醒放入锁定池,释放同步锁使线程回到可运行状态
3.对runing状态的线程加同步锁,使其进入同步阻塞。锁被释放进入可运行状态
三.实现方式
1.继承thread类,重写run方法;
2.实现runnable接口,重写run方法;
3.通过callbale和futuretask创建线程;
4.通过线程池创建线程:
4.1.executorservicee = executors.newcachedthreadpool();//可变大小线程池,按照任务数分配线程
4.2.executorservicee = executors.newfixedthreadpool(3);//固定大小线程池
4.3.executorservicee = executors.newsinglethreadpool(1);//单线程池,相当于固定为1的线程池
四.线程中的异常处理
由于新线程由jvm进行调度执行,如果发生了异常,也不会通知到父线程。
(参考博客: 这里只提概要,不重复造*了)
1.解决方法1:子线程(run方法)中try..catch..
public class childthread implements runnable { public void run() { dosomething1(); try { exceptionmethod();// 可能发生异常的方法 } catch (exception e) { // 处理异常 system.out.println(string.format("handle exception in child thread. %s", e)); } dosomething2(); } }
2.解决方法2:为线程设置“未捕获异常处理器”
3.解决方法3:通过future的get方法捕获(推荐)
在submit之后可以获得一个线程执行结果的futrue对象,如果子线程发生了异常,通过future.get()获取返回值时,可以捕获到异常
子线程代码:
public class childthread implements callable<string> { public string call() throws exception { system.out.println("do something 1"); exceptionmethod(); system.out.println("do something 2"); return "test result"; } private void exceptionmethod() { throw new runtimeexception("childthread1 exception"); } }
父线程代码:
public class main { public static void main(string[] args) { executorservice executorservice = executors.newfixedthreadpool(8); future future = executorservice.submit(new childthread()); try { future.get(); } catch (interruptedexception e) { system.out.println(string.format("handle exception in child thread. %s", e)); } catch (executionexception e) { system.out.println(string.format("handle exception in child thread. %s", e)); } finally { if (executorservice != null) { executorservice.shutdown(); } } } }
上一篇: c#封装DBHelper类
下一篇: docker基础知识之挂载本地目录的方法