1、通过一个 volatile 变量实现

volatile保证了可见性,t2修改了标志位后能马上被t1看到

  1. public class interruptDemo {
  2. static volatile boolean isStop = false;
  3. public static void main(String[] args) {
  4. new Thread(()->{
  5. while(true){
  6. if(isStop){//如果这个标志位被其他线程改为true了
  7. System.out.println(Thread.currentThread().getName()+"\t isStop被修改为true,程序终止");
  8. break;
  9. }
  10. System.out.println("t1 ------hello volatile");//----------------------如果没停止,那就一直打印
  11. }
  12. },"t1").start();
  13. try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
  14. new Thread(()->{
  15. isStop = true;
  16. },"t2").start();
  17. }
  18. }
  19. //--
  20. //t1 ------hello volatile
  21. //t1 ------hello volatile
  22. //t1 ------hello volatile
  23. //t1 ------hello volatile
  24. //t1 ------hello volatile
  25. //t1 ------hello volatile
  26. //t1 ------hello volatile
  27. //t1 isStop被修改为true,程序终止

2、 通过AtomicBoolean(原子布尔型)

  1. public class interruptDemo {
  2. static AtomicBoolean atomicBoolean = new AtomicBoolean(false);
  3. public static void main(String[] args) {
  4. m1_volatile();
  5. }
  6. public static void m1_volatile() {
  7. new Thread(()->{
  8. while(true){
  9. if(atomicBoolean.get()){//如果这个标志位被其他线程改为true了
  10. System.out.println(Thread.currentThread().getName()+"\t isStop被修改为true,程序终止");
  11. break;
  12. }
  13. System.out.println("t1 ------hello volatile");//----------------------如果没停止,那就一直打印
  14. }
  15. },"t1").start();
  16. try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
  17. new Thread(()->{
  18. atomicBoolean.set(true);
  19. },"t2").start();
  20. }
  21. }
  22. //t1 ------hello volatile
  23. //t1 ------hello volatile
  24. //t1 ------hello volatile
  25. //t1 ------hello volatile
  26. //t1 ------hello volatile
  27. //t1 ------hello volatile
  28. //t1 isStop被修改为true,程序终止

3、通过Thread类自带的中断api方法实现

public void interrupt() 实例方法,实例方法 interrupt() 仅仅是设置线程的中断状态为true,发起一个协商而不会立刻停止线程
public static boolean interrupted() 静态方法,Thread.interrupted() 判断线程是否被中断,并清除当前中断状态这个方法做了两件事:1、返回当前线程的中断状态;2、将当前线程的中断状态设为false(这个方法有点不好理解,因为连续调用两次的结果可能不一样。)
public boolean isInterrupted() 实例方法,判断当前线程是否被中断(通过检查中断标志位)

具体来说,当对一个线程,调用interrupt()时:

  1. 如果线程处于正常活动状态,那么会将该线程的中断标志设置为 true,仅此而已。被设置中断标志的线程将继续正常运行,不受影响。所以,interrupt()并不能真正的中断线程,需要被调用的线程自己进行配合才行。
  2. 如果线程处于被阻塞状态(例如处于sleep,wait,join 等状态),在别的线程中调用当前线程对象的interrupt方法,那么线程将立即退出被阻塞状态(中断状态将被清除),并抛出一个InterruptedException异常。
  3. 中断不活动的线程不会产生任何影响。