1. 线程与进程区别
进程:进程是资源分配的最小单位,每个进程都有独立的代码和资源空间,一个进程包含多个线程
线程:线程是cup调度的最小单位,每个线程都有独立的运行栈和程序计数器,同一类的线程共享代码和内存空间
在Java中每当运行一个程序的时候都会至少启动两个线程,一个是main线程,一个是垃圾回收线程。在执行一个类的时候都会启动一个jvm,每个jvm相当于操作系统内的一个线程。
2.实现多线程三种方法
1.继承Thread类
2.实现Runnable接口
3.实现Callable接口,
3.Runnable和Callable
相同点:
1.两者都可以用来实现多线程
2.两者启动线程都需要调用Thread.Start()方法
3.两者都是接口
不同点:
1.Runnable线程执行无返回结果,而Callable执行后又返回
2.Runnable线程当出现异常时只能在线程内部进行处理不能向上层抛出,而Callable可以将异常向上抛出
Callable小例子如下
4.线程生命周期和线程同步
线程生命周期图如下:
线程同步的几种方式:
1.同步方法
2.同步代码块
3.使用局部变量实现同步
4.使用特殊变量实现同步
5.常用线程池
线程池常见参数:
corePoolSize:核心线程池的大小,在没有任务到达时线程池中是没有线程的,若调用prestartAllCoreThreads()或者prestartCoreThread()方法后,线程池会预先创建一个或者corePoolSize个线程,当线程任务数量大于corePoolSize时候会将多余的线程先放入缓存队列。
maximumPoolSize:线程池最大线程数量,表示在线程池中最大能创建这么多个线程,超过此数量的线程任务则会采用任务拒绝策略进行处理
poolSize:线程池当中当前存在的线程个数
keepAliveTime:表示线程的存活时间,这个只有在线程数量大于corepoolSize时候才会起作用,缓存队列中的线程如果在keepAliveTime时间之内没有任务执行就会被回收。
unit:keepAliveTime时间单位
workQueue:任务阻塞队列,用来储等待执行的任务,一般有三种类型,ArrayBlockingQueue,LinkedBlockingQueue,SynchronousQueue
1)ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小;
2)LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;
3)synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。
ThreadFactory:线程工厂,用来创建线程
几种常用线程池:
newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool:创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
newSingleThreadExecutor:创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。
newScheduleThreadPool:创建一个定长的线程池,而且支持定时的以及周期性的任务执行,支持定时及周期性任务执行。