如何让线程暂停
stop方法
package com.juc.c_001_00_thread_end;
import com.util.SleepHelper;
public class T01_Stop {
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (true) {
System.out.println("go on");
SleepHelper.sleepSeconds(1);
}
});
t.start();
SleepHelper.sleepSeconds(5);
t.stop();//直接停止线程 立刻停止 粗暴 如果处于占有锁状态 会立刻释放锁 不做善后工作
}
}
Suspend_Resume
package com.juc.c_001_00_thread_end;
import com.util.SleepHelper;
public class T02_Suspend_Resume {
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (true) {
System.out.println("go on");
SleepHelper.sleepSeconds(1);
}
});
t.start();
SleepHelper.sleepSeconds(5);
t.suspend();//暂停
SleepHelper.sleepSeconds(3);
t.resume();//恢复执行
//持有锁不释放暂停 如果不恢复就一直持有锁不释放
}
}
volatile
package com.mashibing.juc.c_001_00_thread_end;
import com.mashibing.util.SleepHelper;
public class T03_VolatileFlag {
private static volatile boolean running = true;
public static void main(String[] args) {
Thread t = new Thread(() -> {
long i = 0L;
while (running) {
//wait recv accept
i++;
}
System.out.println("end and i = " + i); //4168806262 4163032200
});
t.start();
SleepHelper.sleepSeconds(1);
running = false;
}
}
Interrupt
package com.juc.c_001_00_thread_end;
import com.util.SleepHelper;
/**
* interrupt是设定标志位
*/
public class T04_Interrupt_and_NormalThread {
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (!Thread.interrupted()) {//手工设置标志位 再结束线程
//sleep wait
}
System.out.println("t1 end!");
});
t.start();
SleepHelper.sleepSeconds(1);
t.interrupt();
}
}
LockSupport.park()
package com.juc.c_001_00_thread_end;
import com.util.SleepHelper;
import java.util.concurrent.locks.LockSupport;
public class T05_InterruptAndPark {
public static void main(String[] args) {
Thread t = new Thread(() -> {
System.out.println("1");
LockSupport.park();
System.out.println("2");
});
t.start();
SleepHelper.sleepSeconds(1);
t.interrupt();
}
}
结束线程的方法:
- 自然结束(能自然结束就尽量自然结束)
- stop() 直接停止线程 立刻停止 粗暴 如果处于占有锁状态 会立刻释放锁 不做善后工作
- suspend() //暂停;resume()//恢复执行
- volatile标志,不适合某些场景(比如还没有同步的时候,线程做了阻塞操作,没有办法循环回去)打断时间也不是特别精确,比如一个阻塞容器,容量为5的时候结束生产者, 但是,由于volatile同步线程标志位的时间控制不是很精确,有可能生产者还继续生产一段儿时间
- interrupt() and isInterrupted(比较优雅)
- t.interrupt();//调用这个方法会打断t线程内的sleep方法 提前结束休眠;
t.interrupt();//打断t线程的wait等待;
t2.interrupt();//synchronized:t2在等t1休眠10秒释放锁 即使这个时候对t2标志位进行修改 也不会中断干扰抢锁过程.
t2.interrupt();//不会中断t2的获取ReentrantLock锁状态;
t2.interrupt();//会中断t2的lock.lockInterruptibly(); 直接进入catch块捕获异常 执行finally 不执行别的。
t.interrupt();//打断线程的LockSupport.park();