进程
进程是操作系统进行资源分配的最小单位,有自己独立的地址空间,进程之间在某种程度上是相互隔离的,独立的运行程序,进程之间不能共享资源
进程可以支持多个线程,它们看似同时执行,但互相之间并不同步,一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,而且它们从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,但必须小心,确保它们不会妨碍同一进程里的其它线程
线程
线程也称作轻量级进程。是操作系统的最小调度单位,就象进程一样,线程在程序中是独立的、并发的执行路径,每个线程有它自己的堆栈、自己的程序计数器和自己的局部变量。但是,与分隔的进程相比,进程中的线程之间的隔离程度要小。它们共享内存、文件句柄和其它每个进程应有的状态。每个 Java 程序都至少有一个线程 ― 主线程。当一个 Java 程序启动时,JVM 会创建主线程,并在该线程中调用程序的 main() 方法。
java 线程的生命周期中的几种状态
在 java.lang.Thread 类中内部定义了一个枚举类State,该枚举类定义了线程生命周期的中对应的各种状态:
public enum State {
/** * Thread state for a thread which has not yet started. 新建状态,还没有调用start()方法执行 */
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable 可运行线程的线程状态。
* state is executing in the Java virtual machine but it may 可运行的状态在Java虚拟机中执行,但可能
*正在等待操作系统的其他资源,如处理器
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* 线程阻塞 :等待临界区的锁的线程状态。
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock 一个线程因为等待临界区的锁被阻塞产生的状态
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}. 调用wait()方法会导致当前线程阻塞
* 处于阻塞状态的线程正在等待锁,以便获得锁在调用后进入
* 同步块/方法或重新输入同步块/方法
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* 由于调用以下方法之一,线程处于等待状态:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action. 于等待状态的线程正在等待另一个线程执行特定操作。
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
* 例如,一个在对象上调用Object.wait()的线程正在等待另一个线程调用该对象的Object.notify()或
* Object.notifyAll()。 已调用Thread.join()的线程正在等待指定的线程终止。
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* 指定等待时间的线程等待状态。 由于在调用以下方法之一指定了等待时间,因此线
* 程处于定时等待状态:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* 终止状态:线程执行完毕
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
`
1、NEW(新建)
创建后尚未启动的线程处于这个状态。意思是这个线程对象只是被创建了,还没有调用start()方法启动
2、 RUNNABLE(可运行状态)
可运行状态,其实包含着两种细分的状态,一个是 已准备好(Ready),一个是正在运行(Runing)因为一个线程调用start()方法后,Cpu不一定就立马为该线程分配时间片,也有可能就创建后,就被分配了时间片,所以说线程此时的状态可能是正在运行,也能是在等待系统分配资源,RUNNABLE状态也可以理解为存活着正在尝试征用CPU的线程(有可能这个瞬间并没有占用CPU,但是它可能正在发送指令等待系统调度)。由于在真正的系统中,并不是开启一个线程后,CPU就只为这一个线程服务。
3、BLOCKED(阻塞状态)
BLOCKED称为阻塞状态,或者说线程已经被挂起,原因通常是它在等待一个“锁”,当一个线程试图获取一个内部的对象锁(非java.util.concurrent库中的锁),而该锁被其他线程持有,则该线程进入阻塞状态,(wait()方法的调用可能会造成线程进入BLOCKED状态,因为被唤醒后,运行还需要获得调用wait()方法时释放的对象锁)
阻塞和等待
阻塞:进入阻塞是被动的,当一个线程视图去获取一个锁对象,而这个锁对象被其他线程所持有,这时该线程会被阻塞
等待:进入等待是主动的,等待是指是在等待一段时间 后或者 有唤醒动作后,才会退出等待,如主动调用Object.wait(),如无法获取到ReentraantLock,主动调用LockSupport.park(),如主线程主动调用subThread.join(),让主线程等待子线程执行完毕再执行。
4 、WAITING(无限期等待)
处于这种状态的线程不会被分配CPU执行时间,它们要等待显示的被其它线程唤醒。这种状态通常是指一个线程拥有对象锁后进入到相应的代码区域后,调用相应的“锁对象”的wait()方法操作后产生的一种结果。变相的实现还有LockSupport.park()、Thread.join()等,它们也是在等待另一个事件的发生,也就是描述了等待的意思。以下方法:wait()方法,Thread.join(),LockSupport.park()(ReentrantLock.lock() ,操作后进入的是WAITING状态,其内部调用的是LockSupport.park()方法)等调用会使线程进入该状态
5、TIMED_WAITING(限期等待)
处于这种状态的线程也不会被分配CPU执行时间,不过无需等待被其它线程显示的唤醒,在一定时间之后它们会由系统自动的唤醒。以下方法:Thread.sleep(),wait(long),Thread.join(long),LockSupport.parkNanos(),LockSupport.parkUntil()
6、6、TERMINATED(终止状态)
线程运行结束,也就是说run()方法运行完毕,这只是Java语言级别的一种状态,在操作系统内部可能已经注销了相应的线程,或者将它复用给其他需要使用线程的请求,而在Java语言级别只是通过Java代码看到的线程状态而已。