Java多线程编程核心技术(第3版)
上QQ阅读APP看书,第一时间看更新

1.11.3 清除中断状态的使用场景

this.interrupted()方法具有清除状态标志值为false的功能,借用此特性可以实现一些效果,这里简单测试一下。

本节要实现的效果是在MyThread线程中向list1和list2存放数据,基于职责单一原则,MyThread线程只负责存放数据,不负责处理存放的数据量,数据量由main线程进行处理。创建测试项目clearStatus。

创建工具类代码如下:


package tools;

import java.util.ArrayList;

public class Box {
    public static ArrayList list1 = new ArrayList();
    public static ArrayList list2 = new ArrayList();

}

创建线程类代码如下:


package test1;

import tools.Box;

public class MyThread extends Thread {
    @Override
    public void run() {
        try {
            while (true) {
                if (this.isInterrupted()) {
                    throw new InterruptedException("线程被中断!");
                }
                // 模拟执行任务的耗时,不能使用sleep,遇到interrupt()方法会出现异常,
                // 所以用for循环实现
                for (int i = 0; i < 10000; i++) {
                    new String("" + Math.random());
                }
                Box.list1.add("生产数据A");
                System.out.println("list1 size=" + Box.list1.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        try {
            while (true) {
                if (this.isInterrupted()) {
                    throw new InterruptedException("线程被中断!");
                }
                for (int i = 0; i < 10000; i++) {
                    new String("" + Math.random());
                }
                Box.list2.add("生产数据B");
                System.out.println("list2 size=" + Box.list2.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

创建运行类代码如下:


package test1;

import tools.Box;

public class Test1 {
    public static void main(String[] args) throws InterruptedException {
        MyThread t = new MyThread();
        t.start();
        boolean list1Isinterrupted = false;
        boolean list2Isinterrupted = false;
        while (t.isAlive()) {
            if (Box.list1.size() > 500 && list1Isinterrupted == false) {
                t.interrupt();
                list1Isinterrupted = true;
            }
            if (Box.list2.size() > 600 && list2Isinterrupted == false) {
                t.interrupt();
                list2Isinterrupted = true;
            }
            Thread.sleep(50);
        }
    }
}

运行程序后控制台输出结果如下:


list1 size=511
list1 size=512
java.lang.InterruptedException: 线程被中断!
    at test1.MyThread.run(MyThread.java:11)
java.lang.InterruptedException: 线程被中断!
    at test1.MyThread.run(MyThread.java:28)

从输出结果可以发现,并未向list2中添加数据,因为使用了isInterrupted()方法作为判断条件,该方法不会清除中断状态,多次调用isInterrupted()方法的返回值永远是true。同时,进程状态一直呈红色,说明main线程一直在while(true)循环执行,程序出现了错误。

继续实验。

创建线程类代码如下:


package test2;

import tools.Box;

public class MyThread extends Thread {
    @Override
    public void run() {
        try {
            while (true) {
                if (this.interrupted()) {
                    throw new InterruptedException("线程被中断!");
                }
                // 模拟执行任务的耗时,不能使用sleep,遇到interrupt()方法会出现异常,
                // 所以用for循环实现
                for (int i = 0; i < 10000; i++) {
                    new String("" + Math.random());
                }
                Box.list1.add("生产数据A");
                System.out.println("list1 size=" + Box.list1.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        try {
            while (true) {
                if (this.interrupted()) {
                    throw new InterruptedException("线程被中断!");
                }
                for (int i = 0; i < 10000; i++) {
                    new String("" + Math.random());
                }
                Box.list2.add("生产数据B");
                System.out.println("list2 size=" + Box.list2.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

创建运行类代码如下:


package test2;

import tools.Box;

public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        MyThread t = new MyThread();
        t.start();
        boolean list1Isinterrupted = false;
        boolean list2Isinterrupted = false;
        while (t.isAlive()) {
            if (Box.list1.size() > 500 && list1Isinterrupted == false) {
                t.interrupt();
                list1Isinterrupted = true;
            }
            if (Box.list2.size() > 600 && list2Isinterrupted == false) {
                t.interrupt();
                list2Isinterrupted = true;
            }
            Thread.sleep(50);
        }
    }
}

程序运行结果如下:


list1 size=1
list1 size=2
......
list1 size=503
list1 size=504
list1 size=505
list1 size=506
list1 size=507
list1 size=508
java.lang.InterruptedException: 线程被中断!
    at test2.MyThread.run(MyThread.java:11)
list2 size=1
list2 size=2
......
list2 size=616
list2 size=617
list2 size=618
list2 size=619
java.lang.InterruptedException: 线程被中断!
    at test2.MyThread.run(MyThread.java:28)

成功向2个list中添加数据,并且进程按钮为灰色,表示进程销毁,程序没有出现问题。