《Java 多线程编程核心技术》笔记——第1章 Java 多线程技能(二)

文章目录1.7 停止线程1.7.1 停止不了的线程1.7.2 判断线程是否是停止状态1.7.3 能停止的线程——异常法1.7.4 在沉睡中停止1.7.5 能停止的线程——暴力停止1.7.6 方法 stop() 与 java.lang.ThreadDeath 异常1.7.7 释放锁的不良后果1.7.8 使用 return 停止线程1.8 暂停线程1.8.1 suspend 与 resume 方法的使用1.8.2 suspend 和 resume 方法的缺点——独占1.8.3 suspend 和 resume
摘要由CSDN通过智能技术生成

声明:

本博客是本人在学习《Java 多线程编程核心技术》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。

本博客已标明出处,如有侵权请告知,马上删除。

1.7 停止线程

停止一个线程意味着在线程处理完任务之前停掉正在做的操作,也就是放弃当前操作。

在 Java 中有以下三种方法可以终止正在运行的线程:

  1. 使用退出标志,使线程正常退出,也就是当 run() 方法完成后线程终止
  2. 使用 stop() 方法强行终止线程,已废弃,不推荐使用
  3. 使用 interrupt() 方法中断线程,经常使用

1.7.1 停止不了的线程

接下来会使用 interrupt() 方法,但这个方法不会真的停止线程,只是在当前线程中打了一个停止的标记

下面通过一个示例来说明:

  1. 创建一个自定义的线程类

    public class MyThread14 extends Thread {
         
        @Override
        public void run() {
         
            super.run();
            for (int i = 0; i < 500000; i++) {
         
                System.out.println(i);
            }
        }
    }
    
    
  2. 测试类

    public class MyThread14Test {
         
        public static void main(String[] args) {
         
            try {
         
                MyThread14 myThread14 = new MyThread14();
                myThread14.start();
                Thread.sleep(1000);
                myThread14.interrupt();
            } catch (InterruptedException e) {
         
                e.printStackTrace();
            }
        }
    }
    
    

    运行结果

    ...
    499990
    499991
    499992
    499993
    499994
    499995
    499996
    499997
    499998
    499999
    

分析:从运行结果来看,调用 interrupt() 方法并没有停止线程,那该如何停止线程呢?

1.7.2 判断线程是否是停止状态

在介绍如何如何停止线程前,先来看一下如何判断线程的状态是否是停止的。

Thread 类中提供了两种方法

  1. this.interrupted():测试当前线程是否已经是中断状态,当前线程是指运行 this.interrupted() 方法的线程,执行后具有将状态标志清除为 false 的功能
  2. this.isInterrupted():测试线程 Thread 对象是否已经是中断状态,但不清除状态标志

下面通过一个示例来演示 interrupted() 方法的使用:

  1. 创建一个自定义的线程类

    public class MyThread15 extends Thread {
         
        @Override
        public void run() {
         
            super.run();
            for (int i = 0; i < 50000; i++) {
         
                System.out.println(i);
            }
        }
    }
    
    
  2. 测试类

    public class MyThread15Test {
         
        public static void main(String[] args) {
         
            try {
         
                MyThread15 myThread15 = new MyThread15();
                myThread15.start();
                // 让 main 线程休眠 0.5 秒,这样线程规划器会先执行 myThread15 线程
                Thread.sleep(500);
                myThread15.interrupt();
                System.out.println("是否停止1 = " + myThread15.interrupted());
                System.out.println("是否停止2 = " + myThread15.interrupted());
            } catch (InterruptedException e) {
         
                e.printStackTrace();
            }
    
        }
    }
    
    

    运行结果

    ...
    40292
    40293
    40294
    40295
    是否停止1 = false
    40296
    40297
    ...
    40803
    40804
    40805
    是否停止2 = false
    40806
    40807
    40808
    40809
    ...
    

分析:

我们在测试类中调用了以下代码,来停止 myThread15 线程:

myThread15.interrupt();

但在后面又使用了以下代码,来判断当前线程是否停止:

System.out.println("是否停止1 = " + myThread15.interrupted());
System.out.println("是否停止2 = " + myThread15.interrupted());

但打印结果说明当前线程并未停止,再看看 interrupted() 方法的解释:测试当前线程是否已经是中断状态,当前线程是指运行 this.interrupted() 方法的线程

这个当前线程是 main 线程,它从未中断过,所以打印结果是两个 false

接下来让 main 线程产生中断,再看看:

  1. 创建测试类

    public class Test3 {
         
        public static void main(String[] args) {
         
            Thread.currentThread().interrupt();
            System.out.println("是否停止1 = " + Thread.interrupted());
            System.out.println("是否停止2 = " + Thread.interrupted());
        }
    }
    
    

    运行结果

    是否停止1 = true
    是否停止2 = false
    

分析:第一次调用 interrupted() 判断当前线程已经是中断状态了,然后清除了状态标志,所以第二次调用 interrupted() 方法的返回值是 false

介绍完 interrupted() 方法,下面通过一个示例来演示 isInterrupted() 方法的使用:

  1. 创建测试类

    public class MyThread15Test_2 {
         
        public static void main(String[] args) {
         
            try {
         
                MyThread15 myThread15 = new MyThread15();
                myThread15.start();
                // 让 main 线程休眠 0.5 秒,这样线程规划器会先执行 myThread15 线程
                Thread.sleep(500);
                myThread15.interrupt();
                System.out.println("是否停止1 = " + myThread15.isInterrupted());
                System.out.println("是否停止2 = " + myThread15.isInterrupted());
            } catch (InterruptedException e) {
         
             e.printStackTrace();
            }
     }
    }
    
    

    运行结果

    ...
    48254
    48255
    48256
    48257
    是否停止1 = true
    是否停止2 = true
    48258
    48259
    48260
    ...
    

分析:从打印结果上来看,测试 myThread15 线程已经是中断状态了,而且 isInterrupted() 方法并不清除状态标志,所以打印了两个 true

1.7.3 能停止的线程——异常法

有了前面学习的知识,就可以在 for 语句中判断一下线程是否是中断状态了,如果是中断状态,则后面的代码不再运行即可。

下面通过一个示例来演示异常法停止线程:

  1. 创建一个自定义的线程类

    public class MyThread16 extends Thread {
         
        @Override
        public void run() {
         
            super.run();
            try {
         
                for (int i = 0; i < 50000; i++) {
         
                    // 如果是中断状态就不再执行后面的代码了
                    if (this.interrupted()) {
         
                        System.out.println("我要退出了...");
                        throw new InterruptedException();
                    }
                    System.out.println(i);
                }
            } catch (InterruptedException e) {
         
                e.printStackTrace();
            }
        }
    }
    
    
  2. 测试类

    public class MyThread16Test {
         
        public static void main(String[] args) {
         
            try {
         
                MyThread16 myThread16 = new MyThread16();
                myThread16.start();
                Thread.sleep(500);
                myThread16.interrupt();
            } catch (InterruptedException e) {
         
                e.printStackTrace();
            }
        }
    }
    
    

    运行结果

    ...
    41332
    41333
    41334
    41335
    41336
    41337
    41338
    我要退出了...
    java.lang.InterruptedException
    	at MyThread16.run(MyThread16.java:9)
    
    

1.7.4 在沉睡中停止

如果线程在 sleep() 状态下停止线程,会是什么效果呢?

下面通过一个示例来演示:

  1. 创建一个自定义的线程类

    public class MyThread17 extends Thread {
         
        @Override
        public void run() {
         
            super.run();
            try {
         
                System.out.println("begin");
                Thread.sleep(100000);
                System.out.println("end");
            } catch (InterruptedException e) {
         
                System.out.println("线程沉睡中被中断,进入 catch !" + " this.interrupted() = "+this.interrupted());
                e.printStackTrace();
            }
        }
    }
    
    
  2. 测试类

    public class MyThread17Test {
         
        public static void main(String[] args) {
         
            try {
         
                MyThread17 myThread17 = new MyThread17();
                myThread17.start()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值