1:NEW状态
package thread.state;
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("线程开始执行!");
}
}
/**
* 线程的新建状态:还未启动的线程所处的状态
*/
public class ThreadState1 extends Thread{
public static void main(String[] args) {
/**
* 当我们进行new MyThread()的时候,jvm要为线程的运行做一些前期准备工作,
* 比如:
* (1)检查线程类是否已被加载、解析、初始化过
* (2)为对象分配空间,并对空间初始化零值
* (3)对对象进行一些类的元数据信息、对象的GC分年代等的设置
* 当完成以上的准备工作时,线程才能进入到下一个RUNNABLE状态。
* 所以说,当业务繁忙需要创建线程时,最好使用线程池,提高效率,减轻jvm压力,
* 当然如果大量的线程频繁的切换上下文,此时多线程的效率当大大折扣。
*/
MyThread myThread = new MyThread();
System.out.println("线程创建之后,处于:"+myThread.getState()+"-的状态!");
}
}
输出结果:
线程创建之后,处于:NEW-的状态!
2:RUNNABLE状态
package thread.state;
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("线程开始执行!");
}
}
/**
* 线程的新建状态:还未启动的线程所处的状态
*/
public class ThreadState1 extends Thread{
public static void main(String[] args) {
/**
* 当我们进行new MyThread()的时候,jvm要为线程的运行做一些前期准备工作,
* 比如:
* (1)检查线程类是否已被加载、解析、初始化过
* (2)为对象分配空间,并对空间初始化零值
* (3)对对象进行一些类的元数据信息、对象的GC分年代等的设置
* 当完成以上的准备工作时,线程才能进入到下一个RUNNABLE状态。
* 所以说,当业务繁忙需要创建线程时,最好使用线程池,提高效率,减轻jvm压力,
* 当然如果大量的线程频繁的切换上下文,此时多线程的效率当大大折扣。
*/
MyThread myThread = new MyThread();
myThread.start();
System.out.println("线程启动之后,处于:"+myThread.getState()+"-的状态!");
}
}
输出结果:
线程启动之后,处于:RUNNABLE-的状态!
线程开始执行!
3:BLOCKED状态
package thread.state;
public class ThreadA extends Thread{
private Object lockObj;
public ThreadA(Object lockObj){
this.lockObj = lockObj;
}
@Override
public void run() {
synchronized (lockObj) {
System.out.println("线程A开始执行!");
long beginTime = System.currentTimeMillis();
while (System.currentTimeMillis() - beginTime < 5000) {
//模拟5s的任务
}
System.out.println("线程A执行任务完毕!");
}
}
}
package thread.state;
public class ThreadB extends Thread{
private Object lockObj;
public ThreadB(Object lockObj){
this.lockObj = lockObj;
}
@Override
public void run() {
synchronized (lockObj) {
System.out.println("线程B开始执行!");
long beginTime = System.currentTimeMillis();
while (System.currentTimeMillis() - beginTime < 5000) {
//模拟5s的任务
}
System.out.println("线程B执行任务完毕!");
}
}
}
package thread.state;
/**
* 线程的新建状态:还未启动的线程所处的状态
*/
public class ThreadState2 extends Thread{
public static void main(String[] args) throws InterruptedException {
Object lockObj = new Object();
//让2个线程 锁定同一个对象 模拟线程的blocked状态
ThreadA threadA = new ThreadA(lockObj);
ThreadB threadB = new ThreadB(lockObj);
threadA.start();
threadB.start();
//因为每个线程 执行任务都需要5s 所以这里主线程休息3s 可以看到一个线程处于blocked状态 一个线程处于RUNNABLE状态
Thread.sleep(3000);
System.out.println("线程A启动之后,处于:"+threadA.getState()+"-的状态!");
System.out.println("线程B启动之后,处于:"+threadB.getState()+"-的状态!");
}
}
输出结果:
线程A开始执行!
线程A启动之后,处于:RUNNABLE-的状态!
线程B启动之后,处于:BLOCKED-的状态!
线程A执行任务完毕!
线程B开始执行!
线程B执行任务完毕!
4:TIMED_WAITING状态
package thread.state;
public class Thread3 extends Thread{
@Override
public void run() {
for(int i=0;i<99;i++){
if(i%10 == 0){
System.out.println("每隔十个数字,输出一个字符串");
}
try {
Thread.sleep(1000);
System.out.println("每个数字停顿一秒!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package thread.state;
/**
* Java文档官方定义TIMED_WAITING状态为:“一个线程在一个特定的等待时间内等待另一个线程完成一个
* 动作会在这个状态”
* 真实生活例子:尽管充满戏剧性,你在面试中做的非常好,惊艳了所有人并获得了高薪工作。(祝贺
* 你!)你回家告诉你的邻居你的新工作并表达你激动的心情。你的朋友告诉你他也在同一个办公楼里工
* 作。他* 建议你坐他的车去上班。你想这不错。所以第一天,你走到他的房子。在他的房子前停好你的 .
* 车。你等了10 * 分钟,但你的邻居没有出现。你继续开自己的车去上班,这样你不会在第一天就迟到。
* 这就是TIMED_WAITING.
* 用技术术语来解释,你是线程T1而你的邻居是线程T2。你释放了锁(这里是停止开车)并等了足足10分
* 钟。如果你的邻居T2没有来,你继续开车。
* 实现一个计数器 0-99计数 在每个数字之间停顿一秒 每隔十个数字输出一个字符串
*/
public class ThreadState3 extends Thread{
public static void main(String[] args) {
Thread3 thread3 = new Thread3();
thread3.start();
/**
* timed_waiting代表线程执行了Thread.sleep()方法,
* 呈等待状态,等待时间到达,继续向下运行。
* 因为 一旦子线程执行 每个数字睡一秒 在此期间 随机cpu切换到主线程 也就
* 执行一次System.out.println("线程启动之后,处于:" + thread3.getState() + "-的状态!");
* 相当于命中1次 子线程的状态 还不一定是waiting状态
* 所以这里我们 也for循环 增大概率 去看子线程的状态
* 所以 这里我们用for循环
*/
for(int i=0;i<100;i++) {
System.out.println("线程启动之后,处于:" + thread3.getState() + "-的状态!");
}
}
}
打印的其中一段结果,可以看到TIMED_WAITING状态:
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
线程启动之后,处于:RUNNABLE-的状态!
每隔十个数字,输出一个字符串
线程启动之后,处于:BLOCKED-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
线程启动之后,处于:TIMED_WAITING-的状态!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每隔十个数字,输出一个字符串
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每个数字停顿一秒!
每隔十个数字,输出一个字符串
5:WAITING状态
package thread.state;
/**
* 实现一个计数器 0-99计数 在每个数字之间停顿一秒 每隔十个数字输出一个字符串
*/
public class ThreadState4 extends Thread{
public static void main(String[] args) throws InterruptedException {
final Object lockObj = new Object();
Thread thread1 = new Thread(()->{
synchronized (lockObj){
try {
lockObj.wait();
System.out.println("线程进入等待!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread1.start();
Thread thread2 = new Thread(()->{
synchronized (lockObj) {
try {
Thread.sleep(3000);
System.out.println("3秒后,唤醒前面沉睡的thread1!");
lockObj.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread2.start();
System.out.println("-----查看thread1的状态是:"+thread1.getState());
Thread.sleep(4000);
System.out.println("查看thread1的状态是:"+thread1.getState());
}
}
输出结果:
-----查看thread1的状态是:WAITING
3秒后,唤醒前面沉睡的thread1!
线程进入等待!
查看thread1的状态是:TERMINATED