一、创建线程的三种方法
1、实现 Runnable 接口
2、继承 Thread 类本身
3、通过 Callable 和 Future 创建线程
二、创建线程的三种方式的对比
1. 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。
2、使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。
3、使用Callable 接口的方式创建线程,可以直接获取到线程的执行结果。
三、线程池
大家都很熟悉的连接池,比如我们在用java操作MySQL的时候,我们都会建一个连接池,为什么要建连接池呢,因为连接的创建是非常耗时的,如果每次访问MySQL都有出创建连接的话,就会使程序的性能出现很大的波动。同理,我们创建线程也是非常昂贵的,线程可以循环利用,当一个任务执行完毕以后接着执行下面一个任务。
JDK给我们提供一个线程池的执行器:ThreadPoolExecutor,通过此类就可以很原始的创建一个线程池。
1、ThreadPoolExecutor的四个构造方法:
2、我们看一下ThreadPoolExecutor的构造方法的参数:
2.1、int corePoolSize:核心线程池大小 2.2、int maximumPoolSize:最大线程池大小 2.3、long keepAliveTime:当线程池中空闲线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁; 2.4、TimeUnit unit:keepAliveTime的单位 2.5、BlockingQueue<Runnable> workQueue:任务队列,被添加到线程池中,但尚未被执行的任务;它一般分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种 2.6、ThreadFactory threadFactory:线程工厂,用于创建线程,一般用默认即可 2.7、RejectedExecutionHandler handler:拒绝策略;当任务太多来不及处理时,如何拒绝任务
3、我们看到用ThreadPoolExecutor来创建线程池太麻烦了,7个参数设置起来比较麻烦,有没有更简洁的方式呢?既然都说到这个份上了,那就肯定是有的,我们看Executors这个类,这个类里面提供了很多的静态方法可以直接创建出平时我们用的线程池: