目录
一,Thread类的几个属性
⭐①ID 是线程的唯⼀标识,不同线程不会重复
②名称是各种调试工具用到
③状态表示线程当前所处的⼀个情况,下⾯我们会进⼀步说明
⭐④优先级高的线程理论上来说更容易被调度到
⑤关于守护线程(后台线程),需要记住⼀点:JVM会在⼀个进程的所有非后台线程结束后,才会结束运行。
⑥是否存活,即简单的理解,为 run 方法是否运行结束了
线程的中断问题
属性:状态 -getState()
Thread thread = new Thread(() ->{
System.out.println("当前线程的状态1" + Thread.currentThread().getState());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("当前线程的状态2" + thread.getState());
thread.start();
属性:ID和Name–getId()和getName()
/**
* 线程属性
* ID和名称 ;ID一定是不同的,是动态分配的
* 线程名称手动设置
*/
public class ThreadDemo11 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Thread t = Thread.currentThread();
System.out.println("线程ID" + t.getId());
System.out.println("线程名称" + t.getName() );
}
});
thread.start();
}
}
属性:优先级-getPriority()
/**
* 获取优先级
*/
public class ThreadByPriority {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// 得到当前线程,并打印线程的优先级
Thread thread1 = Thread.currentThread();
System.out.println("线程优先级1:" + thread1.getPriority());
}
});
System.out.println("线程优先级2:" + thread.getPriority());
thread.start();
}
}
属性:是否守护线程-isDaemon()
//在主线程创建子线程
Thread t = new Thread(()->{
Thread t1 = Thread.currentThread();
System.out.println(t1.getName() + "是否守护线程" + t1.isDaemon());
// 创建子线程
Thread tt1 = new Thread(() -> {
Thread cThread2 = Thread.currentThread();
System.out.println(cThread2.getName() + "——是否守护线程:" + cThread2.isDaemon());
}, "子线程的子线程1");
tt1.start();
},"子线程1");
属性:是否存活-isAlive()
/**
* 线程是否存活 isAlive() -while循环
*/
public class DaemonThreadAlive {
public static void main(String[] args) {
Thread t = new Thread(() ->{
for(int i=0;i < 10;i++){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("执行完了");
});
t.start();
//判断是否存活
while(t.isAlive()){
}
System.out.println("确认执行完了");
}
}
二,启动一个线程-start()
线程对象可以认为是把 李四、王五叫过来了。
而调用 start() 方法,就是喊⼀声:”行动起来!“,线程才真正独立去执行了
Thread thread = new Thread(()->{
//业务代码
Thread thread3 = Thread.currentThread();
System.out.println("名称" + thread3.getName());
});
//启动线程
thread.start();
三,中断线程的方法
目前常见的有以下两种方式:
1.通过共享的标记来进行沟通
//声明一个自定义标识符
private volatile static boolean flag = false;
/**
* 自定义标识符终止线程
*/
public class InterruptThread1 {
//声明一个自定义标识符
private volatile static boolean flag = false;
public static void main(String[] args) {
Thread thread = new Thread(() -> {
while(!flag){
System.out.println("正在转账");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("差点误了大事");
});
thread.start();
System.out.println("执行结束");
}
}
标志位是否清除
标志位是否清除, 就类似于一个开关.
Thread.isInterrupted() 相当于按下开关, 开关自动弹起来了. 这个称为 "清除标志位"
Thread.currentThread().isInterrupted() 相当于按下开关之后, 开关弹不起来, 这个称为**“不清除标志位”.**
2.调用 interrupt() 方法来通知
//终止线程
thread.interrupt();
System.out.println(“终止交易”);
thread.start();
Thread.sleep(1000);
//终止线程
thread.interrupt();
System.out.println("终止交易");
System.out.println("终止标志位3" + Thread.currentThread().isInterrupted());
3,interrupted和isInterrupted的区别
①interrupted是静态方法,所有程序都可以使用的全局方法,isInterrupted是某个实例的方法
②interrupted在使用完后会重置标识符isInterrupted不会重置
具体分析请看
链接: https://blog.csdn.net/qq_55660421/article/details/123662613.
四,等待一个线程-join()
有时,我们需要等待一个线程完成它的工作后,才能进行自己的下一步工作。例如,李四只有等张三工作成功,才决定是否工作,这时我们需要一个方法明确等待线程的结束
public class ThreadByJoin {
public static void main(String[] args) throws InterruptedException{
Thread t1 = new Thread(() -> {
// 1.张三开始上班
System.out.println("1.张三开始上班");
// 2.张三正在上班
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 3.张三下班
System.out.println("3.张三下班");
});
// 启动程序
t1.start();
// while (t1.isAlive()) {
// }
// 等待线程 t1 执行完之后,再执行后面的代码
t1.join();
Thread t2 = new Thread(() -> {
// 1.李四开始上班
System.out.println("1.李四开始上班");
// 2.李四正在上班
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 3.李四下班
System.out.println("3.李四下班");
});
t2.start();
}
}
五,休眠当前线程
休眠线程有两种实现:
使用 sleep 休眠
也是我们比较熟悉一组方法,有一点要记得,因为线程的调度是不可控的,所以,这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间的
/**
* 休眠线程
*/
public class ThreadSleep {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
System.out.println("我接收到了中止执行的通知");
// e.printStackTrace();
}
}
});
t.start();
//休眠线程
Thread.sleep(1000);
System.out.println("终止子线程 thread");
t.interrupt();//终止线程
}
}
使用 TimeUnit 休眠
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
/**
* 休眠线程
*/
public class ThreadTimeUtil {
public static void main(String[] args) throws InterruptedException {
System.out.println("主线程开始执行了:" + LocalDateTime.now());
TimeUnit.SECONDS.sleep(3); // 休眠 3s
System.out.println("主线程又开始执行了:" + LocalDateTime.now());
}
}
六,获取当前线程的引用
public class ThreadDemo {
public static void main(String[] args) {
Thread thread = Thread.currentThread();
System.out.println(thread.getName());
}
}