0 基础概念
并行:指多个任务同时执行而不是交替执行。
并发:指一段时间内以交替的方式去完成多个任务。
处理器可以以时间片分配的技术来实现同一段时间运行多个线程。因此,一个处理企就可以实现并发,而并行则需要靠多个处理器在同一时刻各自运行一个线程来实现。
多线程编程的好处:
- 提高系统的吞吐率:多线程编程可以在一个进程中处理多个并发的操作,比如一个线程因为IO操作而处于等待时,其他线程仍然可以执行其它操作。
- 提高响应性能:在使用多线程情形下,慢的操作可能并不会影响其它的操作,比如web请求总,一个慢的请求处理并不会影响其他请求的处理。
- 充分利用多核处理器资源:适当的多线程分布可以充分利用处理器资源。
- 最小化对系统资源的使用:相对多进程而言,一个进程中的多个线程可以共享其所申请的资源,比如内存。
多线程编程可能碰到的问题:
- 线程安全:多个线程共享数据时,如果没有采取相应的并发访问控制措施,可能会产生数据一致性问题,如读取脏数据即过期数据、丢失更新(某线程的更新被其他线程的更新所覆盖)等。
- 线程活性:死锁(指两个或两个以上的线程或进程在运行过程中,因为资源竞争而造成相互等待的现象,若无外力作用则不会解除等待状态,它们之间的执行都将无法继续下去)、活锁(指正在执行的线程或进程没有发生阻塞,但由于某些条件没有满足,导致反复重试-失败-重试-失败的过程。与死锁最大的区别在于:活锁状态的线程或进程是一直处于运行状态的,在失败中不断重试,重试中不断失败,一直处于所谓的“活”态,不会停止)、饥饿(指一条长时间等待的线程无法获取到锁资源或执行所需的资源,而后面来的新线程反而“插队”先获取了资源执行,最终导致这条长时间等待的线程出现饥饿)。
- 上下文切换:处理器从执行一个线程转向执行另外一个线程的时候操作系统所做的动作被称为上下文切换。
1 Java线程
在Java中创建一个线程就是创建一个Thread类(或其子类)的实例。每个线程都有其执行的任务,线程的任务处理逻辑可以在Thread类的run方法中直接实现或者通过该方法调用相关处理函数,因此run方法相当于线程的任务处理逻辑的入口方法,它由Java虚拟机在运行相应线程时直接调用,而不是由应用代码进行调用。
运行一个线程实际上就是让Java虚拟机执行该线程的run方法,从而使该线程的任务处理逻辑得以执行。Thread类的start方法可以启动一个线程。启动一个线程的实质是请求Java虚拟机运行相应的线程,而这个线程具体何时能够运行时由线程调度器Scheduler决定的。因此,start方法调用结束并不意味着相应线程已经开始运行,这个线程可能稍后才能运行,也可能永远也不会被运行。
Java平台中的线程不是孤立的,线程与线程之间存在一定的联系,比如父子关系。main方法中直接创建的线程都是main线程的子线程,这些子线程所执行的