1、继承Thread类
Thread类本质上是实现了Runnable接口的一个实例,代表了一个线程的实例。启动线程的唯一方法就是调用Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。多个线程之间无法共享线程类的实例变量。2、实现Runnable接口
使用Runnable接口创建的多个线程是可以共享线程类的实例变量,这是因为多个线程可以共享同一个target,所以多个线程可以共享同一个线程类(target类)的实例属性。3、通过Executors创建线程池
3.1、一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
newSingleThreadExecutor,示例:ExecutorService pool = Executors.newSingleThreadExecutor();
3.2、创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
newFixedThreadPool,示例:ExecutorService pool = Executors.newFixedThreadPool(10);
3.3、创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲的线程,当任务数增加时,此线程池又添加新线程来处理任务。
newCachedThreadPool,示例:ExecutorService pool = Executors.newCachedThreadPool();
3.4、此线程池支持定时以及周期性执行任务的需求
newScheduledThreadPool,示例:ScheduledExecutorService pool = Executors.newScheduledThreadPool(10);
4、自定义线程池
public ThreadPoolExecutor(int corePoolSize, //线程池大小,一般线程池开始时是没有线程的,只有当任务来了并且线程数量小于corePoolSize才会创建线程
int maximumPoolSize, //最大线程数,线程池能创建的最大线程数量
long keepAliveTime, //在线程数量超过corePoolSize后,多余空闲线程的最大存活时间
TimeUnit unit, //时间单位
BlockingQueue<Runnable> workQueue, //存放来不及处理的任务的队列,是一个BlockingQueue
ThreadFactory threadFactory, //生产线程的工厂类,可以定义线程名,优先级等
RejectedExecutionHandler handler); //拒绝策略,当任务来不及处理的时候,如何处理