
???点进来你就是我的人了
博主主页:???戳一戳,欢迎大佬指点!
人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习!欢迎志同道合的朋友一起加油喔???
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个?嘿嘿
谢谢你这么帅气美丽还给我点赞!比个心
目录
1.线程的状态
线程共有6种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。分别对应于:新建、运行、阻塞、等待、带超时的等待、终止。
1)新建状态(New)
当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();2)就绪状态(Runnable)
当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;3)运行状态(Running)
当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;4)阻塞状态(Blocked)
处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:1、等待阻塞
运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;2、同步阻塞
线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;3、其他阻塞
通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。5)死亡状态(Dead)
线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
用一张图来将其概括的话会更容易记忆:
2.线程的生命周期

3.线程的状态演示
3.1 NEW和TERMINATED
在这个程序之中,我们首先创建了一个Thread对象,然后运用lambda表达式来实现run方法.在run方法之中什么都不做,只是循环.然后打印在t.start之前和t线程运行完之后,线程所处的状态.其中t,join是为了让main线程等待t线程执行完毕后再继续执行,否则main方法可能会先执行完毕.
public class ThreadDemo1 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
for(int i = 0;i<1000000;i++){
}
});
//t调用start之前,是NEW状态.
System.out.println("线程执行之前:"+t.getState());
t.start();
t.join();
//线程执行完毕之后,就是TERMINATED状态.
System.out.println("线程执行之后:"+t.getState());
}
}
3.2 RUNNABLE和TIME_WAITING
下面代码我们可以看见RUNNABLE,主要是因为我们当前线程的run方法里面没有sleep,join之类的方法,否则在后续打印中就不一定是RUNNABLE状态了.
public class ThreadDemo2 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
for(int i = 0;i<1000;i++){
}
});
System.out.println("线程执行之前:"+t.getState());
t.start();
//线程处于可执行状态
System.out.println("线程运行中:"+t.getState());
t.join();
System.out.println("线程运行完:"+t.getState());
}
}
3.3 WAITING
我们使用wait方法可以使线程出现WAITING状态.在下面代码中,我们使t2线程等待t1线程,当t1线程执行完毕之后,t2线程才开始执行.
public class ThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
Object obj = new Object();
Thread t1 = new Thread(()->{
for(int i = 0;i<1000;i++){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (obj){
obj.notify();
}
System.out.println("线程t1执行完毕!");
});
Thread t2 = new Thread(()->{
synchronized (obj){
try {
obj.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t1.start();
//此时t2没有调用start方法,是NEW
System.out.println("t2 start之前:"+t2.getState());
t2.start();
Thread.sleep(10);
//此时线程t2等待线程t1执行完毕,应该是WAITING状态
System.out.println("t2 wait中:"+t2.getState());
t1.join();
t2.join();
//此时t2执行完毕,TERMINATED
System.out.println("t2执行完成:"+t2.getState());
}
}
3.4 BLOCKED
BLOCKED是阻塞状态,死锁就可能会出现这种状态.在下面代码中,我们创建了两个线程,一个t1,一个t2,我们先让t1获取obj1,然后再获取obj2.然后让t2获取obj2,再获取obj1.这样就可以构成死锁.因为,当t1获取到obj1的时候,t1获取到了obj1锁,t2获取到了obj2锁,他们获取完毕之后.然后他们想要获取对方的锁,此时就构成了死锁.也就出现了BLOCKED状态.
public class ThreadDemo4 {
public static void main(String[] args) throws InterruptedException {
Object obj1 = new Object();
Object obj2 = new Object();
Thread t1 = new Thread(()->{
synchronized (obj1){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (obj2){
}
}
});
Thread t2 = new Thread(()->{
synchronized (obj2){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (obj1){
}
}
});
t1.start();
Thread.sleep(100);
t2.start();
Thread.sleep(1500);
System.out.println(t2.getState());
t1.join();
t2.join();
}
}
