一、线程让步
线程让步就是把当前线程由运行态转变为就绪态,使用yield()方法。
· 示例代码:
· 运行结果:
解释:运行到while处时,检测当前进程的线程数,大于一(除main线程外还有new出来的线程),就让当前线程(main线程)先转为就绪态,new出来的线程全部推出后,main线程再执行
二、线程等待
让当前线程由运行态转变为阻塞态,使用join()方法。
1)join()不传参
public class ThreadJion {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
t.start();
//先将t线程执行完毕再往下执行
//t线程:线程引用对象
//当前线程运行态---》阻塞态 等待(满足一定条件),t线程(不做任何处理,让t继续运行)
//一定条件:1)有传入时间 2)t线程引用对象执行完毕 两个条件任意哪个先执行完就可以
t.join();
System.out.println(Thread.currentThread().getName());
}
}
· 当前线程 运行态—》阻塞态,等待(满足一定条件),t线程(不做任何处理,让t继续运行)
· 一定条件:1)有传入时间 2)t线程引用对象执行完毕 两个条件任意哪个先执行完就可以。
· 结果:
2)join()有参数
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
});
t.start();
t.join(2000);
System.out.println(Thread.currentThread().getName());
}
}
· 结果:
· 等了两秒,虽然t线程没有执行完但传入参数时间到了,就往下执行,验证了两个条件满足一个就可以。
三、线程中断
1)有关api
· 不是真实的中断线程,而是告诉某个线程需要中断,具体是否中断由线程自己决定。
· 了解:stop()中断线程 不安全 以弃用,suspend()挂起一个线程,resume(),dostroy()
2)示例代码
public class InterruptThread {
//中断线程并没有处理中断请求
public static void test1(){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true){
}
}
});
t.start();
t.interrupt();
}
//线程new完先不执行run()而是执行main线程里的方法start和interrupt,完了再去执行run
public static void test2(){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
//线程运行状态时,需要自行判断中断标志位,处理中断操作
while (!Thread.currentThread().isInterrupted()){
System.out.println(Thread.currentThread().getName());
}
}
});
t.start();//t线程中断标志位=false
t.interrupt();//t线程中断标志位=true
}
//打印结果为true false 捕获的异常
public static void test3(){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().isInterrupted());
Thread.sleep(3000);//线程调用wait、join、sleep阻塞时调用中断,会抛异常,通过捕获处理异常,处理中断逻辑,抛出异常后,线程中断标志位会重置
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().isInterrupted());
}
}
});
t.start();//t线程中断标志位=false
t.interrupt();//t线程中断标志位=true
}
//第一个为true后面为false
public static void test4(){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.interrupted());//返回并重置中断标志位
}
}
});
t.start();
t.interrupt();
}
}
总结:
· 自己实现中断标志位
private static volatile boolean IS_INTERRUPTED;
public static void test5(){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
//自定义标志位能满足线程处于运行态的中断操作
/* while (!IS_INTERRUPTED){
System.out.println(Thread.currentThread().getName());
}*/
//自定义标志位满足不了线程处于阻塞状态的中断逻辑
try {
Thread.sleep(99999);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
IS_INTERRUPTED = true;
}
自定义标志位满足不了线程处于阻塞状态的中断逻辑。
加油鸭~