Thread基础
2024-06-23 本文已影响0人
上岸大虾米
1、Thread 方法介绍
1.1 join方法
Thread中的方法,使用方式 thread.join() thread.join(long)
作用是:执行join()方法所在的线程会被阻塞,直到引用join的线程执行结束,此处比较绕,举例说明:
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
IntStream.rangeClosed(1,5).forEach(item -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread run");
});
});
t.start();
// 在main线程中执行 t.join ,表示main线程需要等待t线程运行结束之后才会继续运行
t.join();
// Thread.currentThread().join() 这句表示main线程需要等待main线程执行结束之后才会继续运行,将会一直阻塞
System.out.println("main run");
}
示例2
JoinTest2 启动三个线程,分别是main、t1、t2,由于t2线程中执行t1.join()
,所以t2线程会阻塞直到t1运行结束;main线程中执行t2.join()
,所以会等待t2执行结束后,才会继续执行main后面的代码,最终的现象是,t1,t2,main串行打印输出
public class JoinTest2 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
IntStream.rangeClosed(1,5).forEach(item -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " run");
});
}, "t1");
Thread t2 = new ThreadB(t1);
t2.setName("t2");
t1.start();
t2.start();
// main线程阻塞,直至t2线程执行结束
t2.join();
System.out.println(Thread.currentThread().getName() + " run");
}
}
class ThreadB extends Thread {
Thread t1;
public ThreadB(Thread t1) {
this.t1 = t1;
}
@Override
public void run() {
IntStream.rangeClosed(1,5).forEach(item -> {
try {
TimeUnit.SECONDS.sleep(1);
// 此时,当前线程阻塞,直至t1线程结束
t1.join();
System.out.println(Thread.currentThread().getName() + " run");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
1.2 线程中断
方法 | 描述 |
---|---|
interrupt | 中断此线程,更新线程中断状态,更新至true状态,如果该线程阻塞的调用wait() ,或join() ,或sleep(long) 这些方法,那么它的中断状态将被清除,并且将收到[InterruptedException ] 异常 |
interrupted | 测试当前线程是否已被中断。 此方法清除线程的中断状态 。 换句话说,如果连续两次调用此方法,则第二次调用将返回false |
isInterrupted | 测试此线程是否已被中断。 线程的中断状态不受此方法的影响。 |
1.3 interrupt代码示例
public static void main(String[] args) {
System.out.println("before isInterrupted:" + Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt();
System.out.println("after isInterrupted:" + Thread.currentThread().isInterrupted());
System.out.println("interrupted:" + Thread.interrupted());
System.out.println("isInterrupted:" + Thread.currentThread().isInterrupted());
}
输出:
before isInterrupted:false
after isInterrupted:true
interrupted:true
isInterrupted:false
1.4 抛出异常清除中断状态代码示例
https://blog.csdn.net/cy973071263/article/details/130330598
当调用join、sleep、wait方法抛出InterruptedException
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
IntStream.rangeClosed(1, 5).forEach(item -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
/**
* 抛出异常之后,中断位被清除,所以此处输出为false, 因此建议在catch处
* 重新标记线程中断状态为true,即: Thread.currentThread().interrupt();
*/
System.out.println("throw InterruptedException, isInterrupted=" + Thread.currentThread().isInterrupted());
e.printStackTrace();
}
System.out.println(item);
});
});
t1.start();
t1.interrupt();
}
1.5 . 线程的状态
Thread类中有个State枚举,表示线程的状态,共包含6种状态,分别是:
NEW: 新建未启动时
RUNNABLE:可运行状态
BLOCKED:也称为重量级阻塞,不能够被中断,如调多线程调用synchronized关键字或者synchronized块(持有的锁为同一个)
WAITING:也称为轻量级阻塞,能够被中断,如调用sleep()
TIMED_WAITING:和WAITING一样,区别是WAITING是无期限阻塞,TIMED_WAITING是有期限阻塞,如sleep(10)
TERMINATED:线程已执行完成
使用 jstack -i pid 命令查看线程状态
获取线程状态代码示例
public class ThreadState {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
IntStream.rangeClosed(1,10).forEach(i -> System.out.print(""));
System.out.println();
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1");
System.out.println("before start:" + t1.getState());
t1.start();
System.out.println("after start:" + t1.getState());
TimeUnit.SECONDS.sleep(1);
System.out.println("sleep state:" + t1.getState());
TimeUnit.SECONDS.sleep(3);
System.out.println("thread run end:" + t1.getState());
Thread t2 = new Thread(() -> {
run();
}, "t2");
t2.start();
TimeUnit.SECONDS.sleep(1);
System.out.println("call wait state:" + t2.getState());
Work work = new Work();
Thread work1 = new Thread(() -> {
work.work();
}, "work1");
Thread work2 = new Thread(() -> {
work.sleep();
}, "work2");
work1.start();
TimeUnit.SECONDS.sleep(1);
// 此时t2的状态是BLOCKED
work2.start();
}
private synchronized static void run() {
try {
ThreadState.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class Work {
public synchronized void work() {
while (true) {
}
}
public synchronized void sleep() {
while (true) {
}
}
}
}
输出
before start:NEW
after start:RUNNABLE
sleep state:TIMED_WAITING
thread run end:TERMINATED
call wait state:WAITING
通过jstack
查看work2线程状态为:BLOCKED