前言
- 线程是java开发的核心概念。不理解线程的生命周期是无法理解并发和多线程编程的。下面我会以状态机的形式介绍一下线程的生命周期.
线程
- 线程的生命周期有6个状态:
New, Runnable, Blocked, Waiting, Time_waiting, terminated -
下面看一下它的状态流转:
image.png
NEW:Thread已经被创建,但是还没有start的时候
public class ThreadTest {
public static void main(String[] args) {
ThreadState threadState = new ThreadState();
Thread thread = new Thread(threadState);
System.out.println("现在线程的状态: " + thread.getState());
}
}
class ThreadState implements Runnable {
@Override
public void run() {
}
}
-
输出
image.png
Runnable:thread启动之后的状态,这个状态主要是线程调度器操纵,分片策略。根据是否获得所需资源,决定是Ready to run 还是Running,有资源就Running,没有就Ready to run。
public class ThreadTest {
public static void main(String[] args) {
ThreadState threadState = new ThreadState();
Thread thread = new Thread(threadState);
System.out.println("现在线程的状态: " + thread.getState());
thread.start();
System.out.println("现在线程的状态: " + thread.getState());
}
}
class ThreadState implements Runnable {
@Override
public void run() {
}
}
Blocked:这个状态一般是等待获取进入某个资源或者对象的锁,比如Synchronized。
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ThreadState threadState = new ThreadState();
ThreadState threadState1 = new ThreadState();
Thread thread = new Thread(threadState);
Thread thread1 = new Thread(threadState1);
System.out.println("现在线程的状态: " + thread.getState());
thread.start();
thread1.start();
Thread.sleep(1000);
System.out.println("thread现在线程的状态: " + thread.getState());
System.out.println("thread1现在线程的状态: " + thread1.getState());
}
}
class ThreadState implements Runnable {
@Override
public void run() {
excResource();
}
//第一个进入的线程永远持有这个资源的锁,不释放
public static synchronized void excResource() {
while (true) {
}
}
}
-
资源一旦被线程持有之后不会释放,所以第二个进入的线程会进入BLOCKED状态,一直等到资源释放,当然这种情况在多线程时会带来不必要的资源开销,并发编程中有一些策略就是为了解决锁资源被长时间持有不释放的问题
image.png
Waiting:这个没有time,那么就是和时间没有关系。等待其它线程表现出特定的action,动作触发线程状态变化,有下面三种方法实现:
1.object.wait()
2.thread.join()
3.LockSupport.park()
public class WaitingThreadTest implements Runnable {
public static Thread thread1;
public static void main(String[] args) {
thread1 = new Thread(new WaitingThreadTest());
thread1.start();
}
@Override
public void run() {
//第一个线程生成线程2
Thread thread2 = new Thread(new MyThread2());
thread2.start();
try {
thread2.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class MyThread2 implements Runnable {
@Override
public void run() {
//第二个线程
// try {
// Thread.sleep(1000);
// }
// catch (InterruptedException e) {
// Thread.currentThread().interrupt();
// }
System.out.println("thread2的状态" + Thread.currentThread().getState());
System.out.println("thread1的状态:" + WaitingThreadTest.thread1.getState());
}
}
-
thread2在thread1中创建,并且start,进入Runnable状态,当thread2.join()的时候,thread1,也就是主线程进入waiting的状态,thread2状态不变。
image.png
TIMED_WAITING
- 一个线程等待另外一个线程特定的动作,只会等待一段时间,之后不再等待。进入Runnable状态。
1.thread.sleep(long millis)
2.wait(int timeout) or wait(int timeout, int nanos)
3.thread.join(long millis)
4.LockSupport.parkNanos
5.LockSupport.parkUntil
public class TimedWaitingState {
public static void main(String[] args) throws InterruptedException {
DemoThread obj1 = new DemoThread();
Thread t1 = new Thread(obj1);
t1.start();
//留下一些时间 等待t1线程run方法启动
//主线程进入Timed_waited状态
Thread.sleep(1000);
System.out.println(t1.getState());
}
}
class DemoThread implements Runnable {
@Override
public void run() {
try {
//这个线程不会立即结束
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
Terminated
public class TerminatedState implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new TerminatedState());
t1.start();
// The following sleep method will give enough time for
// thread t1 to complete
//主线程等待
Thread.sleep(1000);
Log.info(t1.getState());
}
@Override
public void run() {
// No processing in this block
//这个线程会马上结束
}
}
- 线程的状态流转是多线程编程的基础。
网友评论