Java多线程并发中部分不并发的问题

写Java实验发现个有意思的问题

三个线程,一个线程打印字符a,一个线程打印字符b,另一个线程打印数字,多次运行结果都是先打印混合输出的ab,完了再打印数字

 有图有真相,我运行了10次

完整的代码是这个

class PrintChar implements Runnable{
    private char charToPrint;
    private int times;
    public PrintChar(char c,int t){
        charToPrint=c;
        times=t;
    }

    @Override
    public void run() {
        for(int i=0;i<times;i++){
            System.out.print(charToPrint);
        }
    }
}
class PrintNum implements Runnable{
    private int lastNum;
    public PrintNum(int n){
        lastNum=n;
    }

    @Override
    public void run() {
        for(int i=0;i<=lastNum;i++){
            System.out.print(" "+i);
        }
    }
}
public class TaskThreadDemo {
    public static void main(String[] args) {
        Runnable printA=new PrintChar('a',100);
        Runnable printB=new PrintChar('b',100);
        Runnable print100=new PrintNum(100);
        Thread thread1=new Thread(printA);
        Thread thread2=new Thread(printB);
        Thread thread3=new Thread(print100);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

字符a和字符b是混合输出的,这符合我们的预期,因为多线程是并发的,因此各个线程之间的输出顺序是不确定

但是我们却从中发现尽管字符a和b的顺序是不确定的,但是ab和数字的顺序却始终是先打印完ab再打印数字,这显然不科学,理论上数字也应该和ab一起混合输出,这究竟是为什么呢,我们观察到代码中,打印数字的线程是最后创建的,而且也是最后才启动的。

会不会是因为这个呢,于是我们改为最先创建打印数字的线程,最先启动打印数字的线程。

再次运行程序,很遗憾的发现,输出结果依然没有发生变化,数字依然在字母之后输出。

于是我们把注意力放到了线程本身进行比较,发现同样是打印,但是打印字母的是直接打印一个固定的字符变量,而打印数字的则是打印一个字符串和整型变量相加的结果。

我们把打印数字的换成一个固定的整形变量lastNum。

再次运行程序10次,结果如下,这次看到了字母ab和数字混合出现的结果,可见原因就出现在我们刚刚替换的代码处。

原本代码处是打印一个字符串和整型变量相加的结果,这里会隐形调用函数将整型变量转换为字符串,因此会比直接打印整型变量多一个函数调用的步骤,因此这里相比之下执行会更慢一些,而Java的线程调度是由操作系统内核来完成的,Java程序中的线程会被映射到操作系统的原生线程上,操作系统负责为这些线程分配CPU时间片,并根据调度策略来进行调度。那么在在默认情况下,Java线程的调度遵循抢占式的时间片轮转调度策略,每个线程都被分配一定的CPU时间片,当线程的时间片用完时,操作系统才会暂停该线程的执行,并将CPU时间片分配给其他等待执行的线程

所以这个CPU时间片足够让线程直接打印一个字符,但是不够让线程调用函数完成整型变量到字符串的转换以及相加的操作,因此在需要多个时间片完成打印数字的任务时,已经足够让打印字母的线程完成任务了。

为了验证我们的解释,我们将原本打印100个字母的线程任务换成了300个,让打印数字的线程有足够的CPU时间片在打印字母的线程还没完成任务的时候就打印出数字。

再次运行程序10次,此时出现了数字和字母混合输出的现象,说明我们的分析是对的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/191335.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

win10下载Remix IDE桌面版以及空白页面的解决

文章目录 Remix IDE 的下载Remix IDE 空白页面的解决 Remix IDE 的下载 到 github 地址 https://github.com/ethereum/remix-desktop/releases 选择exe文件或根据自己电脑版本选择对应的zip文件进行下载&#xff0c;然后正常安装即可。 Remix IDE 空白页面的解决 有时打开Remix…

7 通用数字量输入输出GPIO

文章目录 7.0 GPIO概念7.1 GPIO工作原理7.2 GPIO寄存器以及编程7.2.5 GPIO寄存器编程设置与应用 7.3 GPIO跑马灯7.3.1 LED 输出初始化7.3.2 跑马灯输出实验7.3.3 按键输入实验 7.0 GPIO概念 GPIO&#xff08;general purpose intput output&#xff09;是通用输入输出端口的简…

记一次Kotlin Visibility Modifiers引发的问题

概述 测试环境爆出ERROR告警日志java.lang.IllegalStateException: Didnt find report for specified language&#xff0c;登录测试环境ELK查到如下具体的报错堆栈日志&#xff1a; java.lang.IllegalStateException: Didnt find report for specified language at com.aba.…

7000字详解 动态代理(JDK动态代理 CGLIB动态代理)与静态代理

代理模式 1. 代理模式 概念2. 静态代理3. 动态代理3.1.JDK动态代理3.2.CGLIB动态代理3.3. JDK动态代理和CGLIB动态代理区别 4.静态代理和动态代理区别5.篇末 1. 代理模式 概念 代理模式是一种设计模式。 使用代理对象来替代真实对象&#xff0c;用代理对象去访问目标对象。这样…

笔记(三)maxflow push relabel与图像分割

笔记&#xff08;三&#xff09;maxflow push relabel与图像分割 1. Push-Relabel算法思想2.Push-Relabel算法原理示意图3.Push-Relabel算法具体实例4. push relabel与图割 1. Push-Relabel算法思想 对于一个网络流图: 该算法直观可以这样理解&#xff0c;先在源节点处加入充足…

WordPress无需插件禁用WP生成1536×1536和2048×2048尺寸图片

我们在使用WordPress上传图片媒体文件的时候&#xff0c;是不是看到媒体库中有15361536和20482048的图片文件&#xff0c;当然这么大的文件会占用我们的服务器空间&#xff0c;如何禁止掉呢&#xff1f; function remove_default_image_sizes( $sizes) {unset( $sizes[1536x15…

人力资源管理后台 === 组织架构

目录 1.组织架构-树组件应用 2.组织架构-树组件自定义结构 3.组织架构-获取组织架构数据 4.组织架构-递归转化树形结构 5.组织架构-添加子部门-新建弹层组件 6.组织架构-添加子部门-表单结构 7.组织架构-添加子部门-表单基本校验 8.组织架构-添加子部门-表单业务校验 9…

ATK-ESP8266 WIFI模块串口通信通用实现方案

ATK-ESP8266 WIFI模块是一种常用的无线模块&#xff0c;它可以通过串口与外部设备进行通信&#xff0c;实现数据的收发和控制。本文将介绍一种通用的实现方案&#xff0c;帮助您在项目中使用ATK-ESP8266 WIFI模块进行串口通信。 【方案概述】 这个通用实现方案涵盖了ATK-ESP82…

VMWare虚拟机ubuntu克隆打不开

ubuntu克隆打不开 复制的存有ubuntu克隆的文件夹&#xff0c;导入vmware打不开 说找不到这个文件&#xff0c;那就到目录把它的删掉 的删掉 换000001.vmdk后缀的

Android 10.0 mtp模式下连接pc后显示的文件夹禁止删除copy重命名功能实现

1.前言 在10.0的系统开发中,usb连接pc端的时候有好几种模式,在做otg连接pc端的时候,改成mtp模式的时候,在pc端可以看到产品设备 的显示的文件夹的内容,对于产品设备里面的文件在pc端禁止做删除重命名拷贝等操作功能的实现 2.mtp模式下连接pc后显示的文件夹禁止删除copy重命…

在我国干独立游戏开发有多难?

游戏独立开发在中国&#xff0c;一直以来都是一条充满挑战的道路。尽管有着无限的激情和创意&#xff0c;但面对市场、资金、政策等多方面的困难&#xff0c;许多独立开发者在这条路上艰难前行。 首先&#xff0c;市场竞争激烈是中国游戏独立开发者面临的首要挑战。随着游戏产…

Unsupervised MVS论文笔记(2019年)

Unsupervised MVS论文笔记&#xff08;2019年&#xff09; 摘要1 引言2 相关工作3 实现方法3.1 网络架构3.2 通过光度一致性学习3.3 MVS的鲁棒光度一致性3.4 学习设置和实施的细节3.5.预测每幅图像的深度图 4 实验4.1 在DTU上的结果4.2 消融实验4.3 在ETH3D数据集上的微调4.4 在…

BUUCTF [MRCTF2020]Ez_bypass 1

题目环境&#xff1a;F12查看源代码 I put something in F12 for you include flag.php; $flagMRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}; if(isset($_GET[gg])&&isset($_GET[id])) { $id$_GET[id]; $gg$_GET[gg]; if (md5($id) md5($gg) && $id ! $gg) { …

显示Excel功能区或工具栏的方法不少,其中快捷方式最快

Microsoft Excel是Office套件中最复杂的工具之一&#xff0c;它提供了大量功能&#xff0c;其中大部分都是使用工具栏操作的。缺少工具栏使Excel很难完成工作。 如果Excel中没有这些关键元素&#xff0c;你将无法快速完成工作&#xff0c;因此&#xff0c;可以理解的是&#x…

算法基础之合并集合

合并集合 核心思想:并查集: 1.将两个集合合并2.询问两个元素是否在一个集合当中 基本原理:每个集合用一棵树表示 树根的编号就是整个集合的编号 每个节点存储其父节点&#xff0c;p[x]表示x的父节点 #include<iostream>using namespace std;const int N100010;int p[N];…

RESTful API 架构快速入门 Flask实现

RESTful 简介 1.1 为什么要使用 RESTful 架构&#xff1f; Representational State Transfer&#xff08;REST&#xff09;是一种面向资源的架构风格&#xff0c;广泛应用于网络服务的设计和开发。使用RESTful架构有以下几个优点&#xff1a; 简单性和可扩展性&#xff1a; RE…

springboot 拦截器中使用@Value注解为null

拦截器中获取配置参数为null 代码如下&#xff1a; 解决方式一&#xff1a; 检查你的WebMvcConfigurer实现类&#xff0c;比如我的是CCBWebMvcConfig 将拦截器以bean的形式注入&#xff1a; 我之前的写法是new 一个放进去的&#xff0c;这种会导致Value为null AutowiredJSCCB…

图像分割模型及架构选型介绍(MMSegmentation|sssegmentation等)

参考&#xff1a; https://zhuanlan.zhihu.com/p/618226513 0. 图像分割概述 图像分割通过给出图像中每个像素点的标签&#xff0c;将图像分割成若干带类别标签的区块&#xff0c;可以看作对每个像素进行分类。图像分割是图像处理的重要组成部分&#xff0c;也是难点之一。随…

二次创作Z01语言

目录 一&#xff0c;字符集 二&#xff0c;编译分词 三&#xff0c;token含义 四&#xff0c;Z01翻译成C 五&#xff0c;执行翻译后的代码 六&#xff0c;打印Hello World! 一&#xff0c;字符集 假设有门语言叫Z01语言&#xff0c;代码中只有0和1这两种字符。 二&#…

使用花生壳外网远程ssh访问内网主机 亲测有效

经常会遇到远程访问其他电脑的需求&#xff0c;一般首选向日葵软件&#xff0c;傻瓜式的连接远程桌面控制&#xff0c;非常方便。但是仅限于远程桌面远程协助这种。 对于程序员来说最佳的登录方式是ssh&#xff0c;同时远程桌面连过来的时候分辨率比较低&#xff0c;图形效果相…
最新文章