进程:
处于运行过程中的程序,具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位
进程三特征:
独立性:有自己的独立资源,拥有地址空间,
动态性:正在系统中活动的指令集合,进程具有自己的生命周期和各种不同的状态
并发性:多个进程可以在单个处理器上并发执行,多个进程之间互不影响
线程
线程是轻量级的进程,线程是进程的执行单元。线程在程序中是独立的、并发的执行流。当进程被初始化后,主线程就被创建。
线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈、程序计数器和局部变量,但不拥有系统资源,它与父进程的其他线程一起共享父进程的系统资源。
创建线程的三种方式
- 继承Thread,实现run()方法;
- 类A实现runnable()接口,并完成接口中的run()方法,再创建线程,把类A的实例作为线程的target
- callable接口(可抛出异常、有返回值)——类A实现callable接口,并完成里面的call方法,需要常见一个FutrueTask对象来包装类A,再创建线程,把FutureTask作为该线程的Target;FutureTask的get方法可返回call方法的返回值。但get方法会阻塞线程,直到返回值返回后,线程方能继续执行。
线程的生命周期:
新建、就绪、运行、阻塞、死亡
join线程
Thread提供了让一个线程等待另一个线程的方法
线程A 调用了线程B的join方法,那么线程A将被阻塞,等待线程B执行完毕后,再回复线程A继续执行。
线程同步
synchronized
(包含隐式同步监视器)—
- 可用wait控制当前线程,导致当前线程等待
- notify唤醒此同步监视器上等待的单个线程
- notifyAll唤醒此同步监视器上等待的所有线程
lock 锁
需要显示释放锁,因此经常与try catch块一起用,将释放工作放在finally块中完成
使用阻塞队列控制线程通信
BlockingQueue put/take
线程池
系统启动和销毁新线程的成本比较高,它涉及与操作系统的交互,当程序中需要创建大量生存期短暂的线程时,考虑使用线程池。线程池启动时会创建大量的空闲线程,程序将callable或runnable对象传递给线程池,线程池就会启动一个线程在执行对应的run0方法或者call()方法,当执行结束后,线程并不会死亡,而是重新返回线程池中变为空闲线程,等待下一个任务。
线程池的实现
Executor
工厂类来产生线程池,该工厂类包含如下几个静态工厂方法来创建线程池:
- newCatchedThreadPool() ——具有缓存功能的线程池,系统根据需要创建线程,这些线程将会被缓存在线程池中
- newFixedThreadPool(int nThread)——可重用,具有固定线程数的线程池
- newSingleThreadExecutor()——创建只有一个单线程的线程池,
- newScheduledThreadPool(int corePoolSize)——具有指定线程数的线程池,可以指定延迟后执行线程任务
- newSingleThreadScheduledExecutor()——只有一个线程的线程池,可以在指定延迟后执行
前三种方法返回一个
ExecutorServer
对象,代表一个线程池,可以执行runnable和callable任务;后两个方法返回
ScheduledExecutorServer
线程池,可以指定延迟后执行任务
线程池使用步骤
- 调用Executors类的静态工厂方法,创建一个 ExecutorService对象,该对象代表一个线程池;
- 创建Runnable实现类或Callable实现类的实例,作为线程执行任务;
- 调用ExecutorService对象的submit()(有返回值)或execute()(无返回值)方法,来提交Callable或Runnable实例;
- 当不想提交任何任务时,调用ExecutorService对象的shutdown()方法来关闭线程池
ForkJoinPool 并行执行的线程池实现类
ForkJoinPool是ExecutorService的实现类,是一种特殊的线程池;支持将一个任务拆分成多个“小任务”计算,再把小任务的结果合并成总的计算结果。
使用方式:
- 创建ForkJoinPool实例
- 调用submit(ForkJoinPoolTask task)或者invoke(ForkJoinTask task)方法来执行指定任务
ForkJoinTask代表一个可并行、合并的任务,是个抽象类,有两个抽象子类:
RecursiveAct
ion(表示没有返回值的任务) 和
RecursiveTask
(有返回值的任务)
线程相关类
ThreadLocal类
:给每个线程一个线程局部变量的副本,隔离多线程程序的资源竞争。
同步机制:多线程之间共享资源,达到线程之间互相通信,则用同步机制
包装线程不安全类:
Collections.synchronizedXxx 将集合包装成线程安全类
example:HashMap hm=Collections.synchronizedMap(new HashMap());——创建后立即包装
线程状态变换
新建(new,但未start)
就绪(start)——除处理机,其他资源均到位(由新建转换得到,还可由阻塞状态变换得到,如下所示)
运行:获得处理器,正在执行过程
阻塞:由运行状态转换得到:遇到如下情形会有运行-->到阻塞
- sleep()
- IO阻塞
- 等待同步锁
- 等待通知(notify notifyAll)
- suspend(不常用)
就绪:除了start,可由阻塞状态转换得到,转换条件如下:
- sleep()时间到
- IO方法返回
- 获得同步锁
- 收到通知
- resume
死亡:死亡不可逆,由运行状态转换得到:转换条件如下:
- stop
- Error或Exception
- run/call执行完毕