文档章节

启动线程以及安全终止线程

k
 karma123
发布于 10/15 22:50
字数 654
阅读 9
收藏 0
JDK

启动

使用start()方法可以启动线程。

start()方法的含义是告知线程规划器线程已初始化完毕,可以分给这个线程时间片了(执行run()方法)。

安全终止线程

示例代码

import java.util.concurrent.TimeUnit;

public class Shutdown {
    public static void main(String[] args) throws Exception {
        Runner one = new Runner();
        Thread countThread = new Thread(one, "CountThread");
        countThread.start();
        // 睡眠1秒,main线程对CountThread进行中断,使CountThread能够感知中断而结束
        TimeUnit.SECONDS.sleep(1);
        countThread.interrupt();
        Runner two = new Runner();
        countThread = new Thread(two, "CountThread");
        countThread.start();
        // 睡眠1秒,main线程对Runner two进行取消,使CountThread能够感知on为false而结束
        TimeUnit.SECONDS.sleep(1);
        two.cancel();
    }

    private static class Runner implements Runnable {
        private long             i;

        private volatile boolean on = true;

        @Override
        public void run() {
            while (on && !Thread.currentThread().isInterrupted()) {
                i++;
            }
            System.out.println("Count i = " + i);
        }

        public void cancel() {
            on = false;
        }
    }
}

结果

Count i = 364902562

Count i = 239832801

分析:使用【中断操作】和【volatile修饰的停止标识变量】这两种方式都能够优雅安全地停止线程

代码中target为one时是使用interrupt(),运行中的线程(main主线程)调用线程countThread的interrupt()方法,向countThread线程打了个“招呼”,对countThread线程做了中断操作。我们看JDK源码中interrupt()方法的源码:

看注释:

// Just to set the interrupt flag

说的非常明白,对标识位进行了设置。就是将 interrupt flag 设置为true。将线程的中断标识位 interrupt flag 属性设置为了true。

所以while条件中 Thread.currentThread().isInterrupted() 返回为true。然后代码跳出了while循环。

代码中target为two时是显式地将停止标识变量on(为volatile变量)变为false,然后跳出while循环。

为何说这样停止线程的方式安全优雅?

Thread的stop()方法也可以终止线程,但是很直接暴力,而且可能会引起死锁。

所以stop()方法被被遗弃了。

使用【中断操作】和【volatile修饰的停止标识变量】的方式停止线程,使线程在终止时有机会清理资源

安全终止线程套路总结

1.run()方法中一般都有while条件。

2.将停止标识变量(最好定义为volatile变量,多线程场景下能够立马读取该变量)写入while条件。

3.显式的调用改变停止标识变量的方法,就可以安全而优雅的停止线程了。

© 著作权归作者所有

共有 人打赏支持
k
粉丝 8
博文 86
码字总数 64740
作品 0
丰台
私信 提问
Android 多线程之几个基本问题

Android中的进程和线程 Android中的一个应用程序一般就对应着一个进程,多进程的情况可以参考Android 多进程通信之几个基本问题 Android中更常见的是多线程的情况,一个应用程序中一般都有包...

xxq2dream
09/28
0
0
JAVA多线程10-基础篇-线程终止

本节摘要: 介绍线程中断的原理、阻塞方法以及代码示例 一、为什么需要中断 有哪些场景我们需要中断线程?通常有以下几点: 我们希望在指定的时间内完成任务,但是任务执行时间太久,例如调用...

x_coder
2017/11/01
0
0
《windows核心编程系列》谈谈进程的建立和终止

第二部分:工作机理 第一章:进程 上一章介绍了内核对象,这一节开始就要不断接触各种内核对象了。首先要给大家介绍的是进程内核对象。进程大家都不陌生,它是资源和分配的基本单位,而进程内...

长平狐
2012/10/08
95
0
java多线程学习(一)

相关概念 进程:是一次程序的运行。 线程:在进程中独立运行的子任务。 使用多线程的优点:提升系统的运行效率。 如何使用多线程 2.1继承Thread类 Thread类的结构:public class Thread imp...

kakayang2011
2016/02/28
99
0
Service面试详解

一、service基础 1、Service是什么? 是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。 2、Service和Thread的区别 service运行在主线程中,四大组件之一。Thread 是程序执...

千涯秋瑟
2017/11/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Confluence 6 教程:在 Confluence 中导航

当你对 Confluence 有所了解后,你会发现 Confluence 使用起来非常简单。这个教程主要是针对你使用的 Confluence 界面进行一些说明,同时向你展示在那里可以进行一些通用的任务和操作。 空间...

honeymose
今天
2
0
sed, awk 练习

1. sed打印某行到某行之间的内容 2. sed 转换大小写 将单词首字母转化大写 将所有小写转化大写 3. sed 在某一行最后面添加一个数字 4. 删除某行到最后一行 解析: {:a;N;$!ba;d} :a : 是...

Fc丶
今天
2
0
babel6升级到7,jest-babel报错:Requires Babel "^7.0.0-0", but was loaded with "6.26.3".

自从将前端环境更新到babel7,jest-babel之前是基于babel6的,执行时候就会报:Requires Babel "^7.0.0-0", but was loaded with "6.26.3". 很烦,因为连续帮好几台电脑修复这个问题,所以记...

曾建凯
今天
1
0
探索802.11ax

802.11ax承诺在真实条件下改善峰值性能和最差情况。 如何改善今天的Wi-Fi? 在决定如何改进当前版本以外的Wi-Fi时,802.11ac,IEEE和Wi-Fi联盟调查了Wi-Fi部署和行为,以确定更广泛使用的障碍...

linuxprobe16
今天
2
0
使用linux将64G的SDCARD格式化为FAT32

一、命令如下: sudo fdisk -lsudo mkfs.vfat /dev/sda -Isudo fdisk /dev/sda Welcome to fdisk (util-linux 2.29.2). Changes will remain in memory only, until you decide to wri......

mbzhong
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部