文章目录
- 一. 线程创建(start)
- (一)继承Thread类,重写run
- (二)继承Runnable类,重写run
- (三)Thread匿名内部类重写
- (四)Runnable匿名内部类重写
- (五)lambda表达式
- 二. 线程的关键属性
- (一)线程名称
- (二)线程是否为后台线程
- 1. 前台线程
- 2. 后台线程
- 3. 查看是否是后台线程(isDaemon)
- 4. 设置后台线程(setDaemon)代码及效果图
- (三)线程是否存活
- 1. 是否存活isAlive
- 2. 代码及效果图
- 三. 线程终止(interrupt)
- (一)Java提供的API
- 1. 用法
- 2. 代码及效果图
- (二)手动设置条件
- 1. 用法
- 2. 代码及其效果图
- 四. 线程等待(join)
- (一)定义
- (二)代码及其效果图
- 五. 获取线程引用(currentThread)
- (一)用法
- (二)代码及其效果图
- 六. 线程休眠(sleep)
- (一)定义
- (二)代码
- 七. 线程状态
- (一)NEW
- 1. 定义
- 2. 代码及其效果图
- (二)TERMINATED
- 1. 定义
- 2. 代码及其效果图
- (三)RUNNABLE
- 1. 定义
- 2. 代码及其效果图
- (四)TIMED_WAITING
- 1. 定义
- 2. 代码及其效果图
- (五)WAITING
- 1. 定义
- 2. 代码及其效果图
- (六)BLOCKED&LOCK
- (①)
- (②)
- (③)
一. 线程创建(start)
(一)继承Thread类,重写run
class MyThread extends Thread {@Overridepublic void run() {while (true) {System.out.println("Thread!!!");try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class demo1 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();thread.start();while (true) {System.out.println("main!!!");Thread.sleep(100);}}
}
(二)继承Runnable类,重写run
class MyRunnable implements Runnable {@Overridepublic void run() {while (true) {System.out.println("Thread!");}}
}public class demo2 {public static void main(String[] args) {MyRunnable runnable = new MyRunnable();Thread thread = new Thread(runnable);thread.start();while (true) {System.out.println("main!");}}
}
(三)Thread匿名内部类重写
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:06*/
public class demo3 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread() {@Overridepublic void run() {while (true) {System.out.println("Thread~~");try {Thread.sleep(0);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};thread.start();while (true) {System.out.println("main~~");Thread.sleep(0);}}
}
(四)Runnable匿名内部类重写
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:14*/
public class demo4 {public static void main(String[] args) throws InterruptedException {Runnable runnable = new Runnable() {@Overridepublic void run() {while (true) {System.out.println("thread~");try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};Thread thread = new Thread(runnable);thread.start();while (true) {System.out.println("main~");Thread.sleep(100);}}
}
(五)lambda表达式
public class demo5 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {System.out.println("thread!");try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"阿然");thread.start();while (true) {System.out.println("main!");Thread.sleep(10);}}
}
二. 线程的关键属性
(一)线程名称
线程名字,我们可以通过setName方法来设置线程的名字,方便后期调试
通过getName方法可以获取线程名称
(二)线程是否为后台线程
1. 前台线程
当前台线程还在运行时,即使其他所有线程都运行完,进程也不停止,要等待前台线程结束,进程才结束
2. 后台线程
当所有前台线程运行完毕时,即使后台线程还有任务没有完成,也会终止进程
3. 查看是否是后台线程(isDaemon)
是否是后台线程通过isDeamon方法来查看
Java中线程创建时默认是前台线程
4. 设置后台线程(setDaemon)代码及效果图
public class demo7 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {System.out.println("thread~~~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"thread");thread.setDaemon(true);thread.start();System.out.println(thread.isDaemon());for (int i = 0; i < 1 ; i++) {System.out.println("main");Thread.sleep(1000);}}
}
(三)线程是否存活
1. 是否存活isAlive
Java中Thread对象与CPU内核中的线程是一一对应的,但是有可能出现内核的线程已经摧毁了,而Thread对象还存在的情况
可以使用isAlive方法来查看线程是否存活
2. 代码及效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:38*/
public class demo8 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread!");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();while (true) {System.out.println(thread.isAlive());Thread.sleep(1000);}}
}
三. 线程终止(interrupt)
(一)Java提供的API
1. 用法
1.Java中提供了控制线程结束的方法interrupted与isInterrupted
2. isInterrupted默认是false,在循环中取反使用来运行线程任务
3. 调用interrupt让isInterrupted置为true
4. 需要注意的是sleep休眠函数会使isInterrupted再次置为false
2. 代码及效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:52*/
public class demo10_interrupt {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {System.out.println(Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {//throw new RuntimeException(e);break;}}System.out.println("进程结束");},"thread");thread.start();Thread.sleep(3000);System.out.println("main尝试终止");thread.interrupt();}
}
(二)手动设置条件
1. 用法
1. 手动设置循环关闭条件时,布尔条件需要是成员变量
2. 如果是局部变量那么布尔条件则不能改变,这样达不到关闭循环从而关闭线程的效果
3. 这是因为每次线程调度切换回该线程时,会从重新栈当中调取变量,如果局部变量则存在销毁可能,无法调取
2. 代码及其效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:47*/
public class demo9 {private static boolean isFinish = false;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (!isFinish) {System.out.println("thread~~~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("进程结束");},"thread");thread.start();for (int i = 0; i < 3; i++) {Thread.sleep(1000);}System.out.println("尝试终止进程翁");isFinish = true;}
}
四. 线程等待(join)
(一)定义
1.Java中线程等待函数时join
2. 线程1调用join,线程1就是被等待的线程,要等到线程1结束后才能结束进程
3. join可以设置等待时间,在设定的等待时间结束后,不论线程1是否完成任务,都不再等待,结束进程
4. join会抛出一个InterruptedException异常
(二)代码及其效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:08*/
public class demo11_join {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread ~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("thread 线程结束!");});thread.start();thread.join(4000);System.out.println("main 线程结束!");}
}
五. 获取线程引用(currentThread)
(一)用法
- Java中Thread封装了获取当前线程的API,即currentThread方法
- currentThread方法是静态方法,可以直接用类名Thread调用
(二)代码及其效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-13* Time: 21:46*/
public class demo_currentThread {public static void main(String[] args) {Thread main = Thread.currentThread();Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread@");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("thread 线程结束");});thread.start();for (int i = 0; i < 5; i++) {System.out.println("main@");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("main 结束");}
}
六. 线程休眠(sleep)
(一)定义
1 Java中休眠方法是sleep
2. sleep方法是静态方法,可以直接用Thread调用
3. 调用sleep方法会抛出InterruptedException异常
(二)代码
try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}
七. 线程状态
(一)NEW
1. 定义
线程还未创建的状态,没调用start
2. 代码及其效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:18*/
public class demo12_new {public static void main(String[] args) {Thread thread = new Thread();System.out.println(thread.getState());}
}
(二)TERMINATED
1. 定义
线程终止状态,运行完毕已经结束
2. 代码及其效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:21*/
public class demo13_TERMINATED {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {}});thread.start();while (true) {System.out.println(thread.getState());Thread.sleep(1000);}}
}
(三)RUNNABLE
1. 定义
线程正在运行时状态
2. 代码及其效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:28*/
public class demo14_RUNNABLE {public static void main(String[] args) {Thread thread = new Thread(() -> {while (true) {}});thread.start();System.out.println(thread.getState());}
}
(四)TIMED_WAITING
1. 定义
有时间限制的等待的线程状态
2. 代码及其效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:34*/
public class demo15_TINE_WAITING {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();thread.join(1000*10000);}
}
(五)WAITING
1. 定义
没有时间限制的等待的线程状态
2. 代码及其效果图
package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:39*/
public class demo16_WAITING {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {}});thread.start();thread.join();}
}
(六)BLOCKED&LOCK
阻塞,这里我们只讨论的是加锁后阻塞,提到锁,不得不谈到死锁,有三种情况:
①:一个线程同时加锁两次
②:两个线程两把锁,一个线程获取到一把锁之后,再尝试获取另一把锁时,加锁形成循环,那么就会形成死锁!
③:N个线程M把锁,每个线程运转都需要用到两把锁的时候,就会形成循环,造成死锁阻塞
(①)
观察下方实例,我们可以发现,用 synchronized 的时候对一个线程多次加锁,不会触发阻塞,这说明 synchronized 是可重入锁!
package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 9:53* 一个线程多次加锁*/
public class test1 {public static void main(String[] args) {Object lock = new Object();Thread thread1 = new Thread(() ->{synchronized (lock) {synchronized (lock) {System.out.println("多次加锁!!!");}} });thread1.start();}
}
(②)
观察下面的实例可以看出,线程1 对 lock1 加锁后休眠1s, 再尝试对第二个 lock2 加锁时,会产生阻塞, 这是因为 线程2 已经对 lock2 加锁成功, 又尝试获取 lock1 的时候产生了阻塞, 导致 lock2 没有解锁, 所以 线程1 尝试获取 lock2失败, 产生阻塞, 相互循环, 形成死锁
package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 10:26*/
public class test2 {public static void main(String[] args) {Object lock1 = new Object();Object lock2 = new Object();Thread thread1 = new Thread(() -> {synchronized (lock1) {System.out.println("获取第一把锁: lock1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock2) {System.out.println("尝试获取第二把锁: lock2");}}});Thread thread2 = new Thread(() -> {synchronized (lock2) {System.out.println("获取第一把锁: lock2");synchronized (lock1) {System.out.println("尝试获取第二把锁: lock1");}}});thread1.start();thread2.start();}
}
(③)
通过下方实例,我们可以看出, N个对象M把锁, 当每个人都要嵌套两把锁才能工作时,就会形成阻塞
package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 10:54*/
public class test3 {public static void main(String[] args) {Object lock1 = new Object();Object lock2 = new Object();Object lock3 = new Object();Thread thread1 = new Thread(() -> {synchronized (lock1) {System.out.println("获取第一把锁: lock1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock2) {System.out.println("尝试获取第二把锁: lock2");}}});Thread thread2 = new Thread(() -> {synchronized (lock2) {System.out.println("获取第一把锁: lock2");synchronized (lock3) {System.out.println("尝试获取第二把锁: lock3");}}});Thread thread3 = new Thread(() -> {synchronized (lock3) {System.out.println("获取第一把锁: lock3");synchronized (lock1) {System.out.println("尝试获取第二把锁: lock1");}}});thread1.start();thread2.start();thread3.start();}
}