线程

2018-09-29 04:03:33来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

一、五种状态

 

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进行调度执行,如果发生了异常,也不会通知到父线程。

(参考博客:https://www.cnblogs.com/yangfanexp/p/7594557.html   这里只提概要,不重复造轮子了)

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();

            }

        }

    }

}
父线程代码

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:简单说说SpringMVC

下一篇:MyBatis(3)-映射文件