前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >多线程:为什么在while循环中加入System.out.println,线程可以停止

多线程:为什么在while循环中加入System.out.println,线程可以停止

作者头像
用户1655470
发布于 2018-11-30 03:08:33
发布于 2018-11-30 03:08:33
1.6K00
代码可运行
举报
文章被收录于专栏:chenssychenssy
运行总次数:0
代码可运行
在论坛看到这样一个代码:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StopThread {    private static boolean stopRequested;    public static void main(String[] args) throws InterruptedException {        Thread backgroundThread = new Thread(new Runnable() {            @Override            public void run() {                int i = 0;                while (!stopRequested) {                    i++;                }            }        });        backgroundThread.start();        TimeUnit.SECONDS.sleep(1);        stopRequested = true;    }}

这个我们都知道,由于 stopReqested 的更新值在主内存中,而线程栈中的值不是最新的,所以会一直循环,线程并不能停止。加上 Volatile 关键字后,保证变量的最新值会被更新到主存,线程在读这个变量时候,也会去取最新的,保证数据的可见性。 但是本文的意思不在此,不对 stopReqested 加同步关键字是否就不能停止了呢?不是的。

如下就能停止线程的运行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StopThread {    private static boolean stopRequested;    public static void main(String[] args) throws InterruptedException {        Thread backgroundThread = new Thread(new Runnable() {            @Override            public void run() {                int i = 0;                while (!stopRequested) {                    i++;                    System.out.println(""+i);                }            }        });        backgroundThread.start();         TimeUnit.SECONDS.sleep(1);        stopRequested = true;    }}

如上面所示,加了 System.out.println之后,线程能停止了。有的人会说,println 的源码里面有 synchronized 关键字,所以会同步变量 stopRequested 的值。这种是很不正确的理解,同步关键字同步的是同步块里面的变量,stopRequested 在这个同步代码块之外。 真正的原因是这样的:JVM 会尽力保证内存的可见性,即便这个变量没有加同步关键字。换句话说,只要 CPU 有时间,JVM 会尽力去保证变量值的更新。这种与 volatile 关键字的不同在于,volatile 关键字会强制的保证线程的可见性。而不加这个关键字,JVM 也会尽力去保证可见性,但是如果 CPU 一直有其他的事情在处理,它也没办法。最开始的代码,一直处于试了循环中,CPU 处于一直被饱受占用的时候,这个时候 CPU 没有时间,JVM 也不能强制要求 CPU 分点时间去取最新的变量值。而加了 System.out.println 之后,由于内部代码的同步关键字的存在,导致CPU的输出其实是比较耗时的。这个时候CPU就有可能有时间去保证内存的可见性,于是while循环可以被终止。

其实,也可以在 while 循环里面加上 sleep ,让 run 方法放弃 cpu ,但是不放弃锁,这个时候由于 CPU 有空闲的时候就去按照 JVM 的要求去保证内存的可见性。如下所示。 run 方法里面休息了 3 秒,cpu 有充足的空闲时间去取变量的最新值,所以循环执行一次就停止了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StopThread {    private static boolean stopRequested;    public static void main(String[] args) throws InterruptedException {        Thread backgroundThread = new Thread(new Runnable() {            @Override            public void run() {                int i = 0;                while (!stopRequested) {                    try {                        TimeUnit.SECONDS.sleep(3);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                    System.out.println(i);                }            }        });        backgroundThread.start();        TimeUnit.SECONDS.sleep(1);        stopRequested = true;    }}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java技术驿站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Docker安装Jenkins打包Maven项目为Docker镜像并运行
Jenkins作为CI、CD的先驱者,虽然现在的风头没有Gitlab强了,但是还是老当益壮,很多中小公司还是使用比较广泛的。最近小编经历了一次Jenkins发包,感觉还不错,所以自己学习了一下。网上比较多的教程都是在Linux上搭建Jenkins,小编经过一个星期的探索终于完成了在docker中进行搭建。
掉发的小王
2022/07/11
1.8K0
Docker安装Jenkins打包Maven项目为Docker镜像并运行
基于docker搭建jenkins
Jenkins 的前身是 Hudson 是一个可扩展的持续集成引擎。Jenkins 是一款开源 CI&CD 软件,用于自动化各种任务,包括构建、测试和部署软件。Jenkins 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序。
py3study
2020/08/19
1.2K0
基于docker搭建jenkins
30分钟搞定 Jenkins CI
你想在本地设置中使用 Jenkins CI 进行实验吗?在本文中,我们将设置一个本地 Jenkins CI 服务,为一个简单的 Spring Boot Maven 项目创建一个构建工作,并将创建的 Docker 镜像推送到 DockerHub。这将是一个本地实验的设置,但如果你想尝试一个 Jenkins 插件,它会非常方便。
LinuxSuRen
2019/06/17
9850
Docker 安装 Jenkins 并实现项目自动化部署
Jenkins 是一款开源的持续集成(DI)工具,广泛用于项目开发,能提供自动构建,测试,部署等功能。作为领先的开源自动化服务器,Jenkins 提供了数百个插件来支持构建、部署和自动化任何项目。
码老思
2023/10/19
3.2K0
Docker 安装 Jenkins 并实现项目自动化部署
基于Docker 5分钟解决Jenkins环境搭建问题
Jenkins;一款基于Java开发的开源持续集成工具,可以让打包、发布、自动化测试变的更加简便;由于使用标准的安装会存在一些插件下载、安装、更新的问题;导致很多人还在门口就被拦回去了,无法领略到其优秀的风采。因此这里使用Docker安装一个中国定制版的Jenkins;保证你能在5分钟内就解决掉环境搭建的问题。
一行Java
2022/04/06
9720
基于Docker 5分钟解决Jenkins环境搭建问题
构建部署流水线GitHub+Docker+Jenkins
构建部署流水线能让我们自动化地进行程序构建和部署。在这篇文章中,我们选择GitHub作为源代码管理仓库,构建引擎选择Jenkins,使用Docker作为部署引擎。
山有扶苏
2022/05/07
1.5K0
超简单让.NET Core开发者快速拥有CI/CD的能力-Docker版本
上一篇自动化测试,全面且详细的介绍了从零开始到发布版本的步骤,这是传统的方式,本次为大家带来的是如何在5分钟内使用上docker进行CI/CD,毕竟现在的容器化如火如荼,本示例是基于CentOS-7系统,在示例中, jenkins 和部署 .NET Core 应用程序,都使用 docker 来完成。
梁规晓
2019/11/08
2.3K0
超简单让.NET Core开发者快速拥有CI/CD的能力-Docker版本
jenkins搭建文档
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成
默 语
2024/11/20
1160
jenkins搭建文档
使用 Docker 全自动构建 Java 应用
我们会在 Docker 容器里运行 Jenkins,再使用 Jenkins 启动一个 Maven 容器,用来编译我们的代码,接着在另一个 Maven 容器中运行测试用例并生成制品(例如 jar 包),然后再在 Jenkins 容器中制作 Docker 镜像,最后将镜像推送到 Docker Hub。
LinuxSuRen
2019/12/23
1.5K0
使用 Docker 全自动构建 Java 应用
docker-compose 部署 Jenkins
vim docker-compose.ymlversion: "3.7" services: jenkins: image: jenkins:2.371-jdk11 container_name: jenkins hostname: jenkins restart: always user: root volumes: - /data/jenkins_home:/var/jenkins_home - /etc/localtime:/etc/loca
陳斯托洛夫斯記
2022/10/02
4130
docker安装Jenkins
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
suveng
2019/11/13
5140
使用Docker安装Jenkins
Jenkins Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。 环境准备 腾讯云 硬件配置:2核4G 1M带宽。50G硬盘。 系统配置:CentOS 7.2 Docker安装 请移步查看:CentOS 7 安装 Docker 安装Jenkins 首先不直接从Docker Store上直接Pull Jenkins 的 Image 文件,因为待会需要进行dotnet core 的 Docker自动部署,需
晓晨
2018/06/22
1.8K0
Jenkins + Docker + Gitee自动化部署SpringBoot应用
最近在做毕业设计,遇到一个问题,就是每次编写完一个功能点,就需要重新运行一下项目,然后进行测试,而且项目比较复杂,在本地运行会占用大量的运行内存,导致开发不畅。于是我想着使用Jenkins配合Gitee搭建一个自动化部署平台,并将代码托管到服务器上,这样减轻了本地的电脑压力,也解放了部署的流程。
wangweijun
2022/05/10
9590
Jenkins + Docker + Gitee自动化部署SpringBoot应用
Docker Compose安装部署Jenkins
Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速在集群中部署分布式应用。
甜点cc
2022/09/26
9810
Docker Compose安装部署Jenkins
docker-compose 部署 Jenkins
我司的生产环境由两个网段,一个网段(10.12.x.x)可以出外网,另一个网段(10.14.x.x)不能出外网。 jenkins是部署在10.14网段上,由于该网段不能联网,所以需要配置代理,由10.12网段代理出去。
陳斯托洛夫斯記
2022/10/04
5650
docker-compose 部署 Jenkins
deepin安装docker和一些常用中间件
导读 deepin基于debian docker官网教程:https://docs.docker.com/engine/install/debian/ Portainer基于Docker Swarm,Rancher基于Kubernetes 安装Docker 更新apt sudo apt-get update 查找安装包 apt search docker-ce 安装 sudo apt-get install docker-ce docker-ce-cli containerd.io 测试 sudo d
翟凤玺
2021/12/07
3020
基于Jenkins的CICD
首次启动会因为数据卷data目录没有权限导致启动失败,设置data目录写权限(/usr/local/docker/jenkins_docker/data)
九转成圣
2024/04/10
1410
基于Jenkins的CICD
15min运维之Docker运行Jenkins从开始到放弃
某新环境需要Jenkins,准备用docker "一条run命令搞定"。其他工具用docker屡试不爽,这次Jenkins是从开始到放弃。
码代码的陈同学
2018/07/10
1.1K0
15min运维之Docker运行Jenkins从开始到放弃
【Jenkins+Blue Ocean】docker部署Jenkins,编写Jenkinsfile创建流水线,一篇解决“贼带劲”
@toc 前言 作者主页:https://blog.csdn.net/qq_48450494?type=blog 个人博客:http://ygcloud.work/ Jenkins 是一个持续集成工具
秋意零
2022/05/21
1.7K0
【Jenkins+Blue Ocean】docker部署Jenkins,编写Jenkinsfile创建流水线,一篇解决“贼带劲”
CICD之Jenkins使用
jenkins把项目拉倒jenkins服务器,放到workspace(一般我们的源代码都在这里),开始进行流水线处理。
全栈程序员站长
2022/09/02
5330
推荐阅读
相关推荐
Docker安装Jenkins打包Maven项目为Docker镜像并运行
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档