Java多线程之Thread和Runnable关于共享资源的对比

news/2024/4/28 23:23:40/文章来源:https://blog.csdn.net/qq_42881421/article/details/127424007

背景

Thread和Runnable关于共享资源的对比,网上看到很多不正确的结论如下:

Thread类创建多线程,无法保证多个线程对共享资源的正确操作,而Runnable接口可以保证多个线程对共享资源的正确访问。

得到这个结论的原因如下:

ThreadDemo 

package org.example.bk.multithread;public class ThreadDemo {public static void main(String[] args) {// 1 看起来重复卖票new TicketWindow().start(); // 创建并开启第一个线程对象new TicketWindow().start(); // 创建并开启第二个线程对象}
}class TicketWindow extends Thread {private int tickets = 5;public void run() {while (tickets > 0) {Thread th = Thread.currentThread(); // 获取当前线程String th_name = th.getName(); // 获取当前线程的名字System.out.println(th_name + " 正在发售第 " + tickets-- + " 张票 ");}}
}

运行结果

 从结果中看到每张票都都卖了2次,出现了"重复卖票"的情况。

RunnableDemo 

package org.example.bk.multithread;public class mt06 {public static void main(String[] args) {        TicketWindow1 tw = new TicketWindow1();new Thread(tw, "窗口1").start(); // 创建线程对象并命名为窗口1,开启线程new Thread(tw, "窗口2").start(); // 创建线程对象并命名为窗口2,开启线程}
}class TicketWindow1 implements Runnable {private int tickets = 5;public void run() {while (tickets > 0) {Thread th = Thread.currentThread(); // 获取当前线程String th_name = th.getName(); // 获取当前线程的名字System.out.println(th_name + " 正在发售第 " + tickets-- + " 张票 ");}}
}

运行结果

 从结果来看,每张票只卖了1次。没有"重复卖票"的现象。

其实这种现象并不是Thread和Runnable的不同造成的,而是由于创建线程的方式不同造成的。

1. 从源码层面看Thread和Runnable,Thread实现了Runnable接口,实现多线程的本质还是Runnable接口。

 

2.造成"重复卖票"和"不重复卖票"的原因是什么呢?

"重复卖票"的原因分析:

ThreadDemo:new了两次TicketWindows对象,所以两个TickeWindow对象里面的tickets也是各自的变量,不是同一资源,自然在多线程时各自卖各自的tickets,自然能看到"重复卖票"的现象。

package org.example.bk.multithread;public class ThreadDemo {public static void main(String[] args) {       new TicketWindow().start(); // 创建并开启第一个线程对象new TicketWindow().start(); // 创建并开启第二个线程对象}
}class TicketWindow extends Thread {private int tickets = 5;public void run() {while (tickets > 0) {Thread th = Thread.currentThread(); // 获取当前线程String th_name = th.getName(); // 获取当前线程的名字System.out.println(th_name + " 正在发售第 " + tickets-- + " 张票 ");}}
}

"不重复卖票"的原因分析:

RunnableDemo:只new了TicketWindow1对象1次。所以1个对象里的tickets只有1个变量,所以在多线程卖票时共享这个变量,自然不会出现"重复卖票"的现象。

package org.example.bk.multithread;public class mt06 {public static void main(String[] args) {        TicketWindow1 tw = new TicketWindow1();new Thread(tw, "窗口1").start(); // 创建线程对象并命名为窗口1,开启线程new Thread(tw, "窗口2").start(); // 创建线程对象并命名为窗口2,开启线程}
}class TicketWindow1 implements Runnable {private int tickets = 5;public void run() {while (tickets > 0) {Thread th = Thread.currentThread(); // 获取当前线程String th_name = th.getName(); // 获取当前线程的名字System.out.println(th_name + " 正在发售第 " + tickets-- + " 张票 ");}}
}

这里举反例进行说明

让Thread不重复卖票,让Runnable重复卖票。

ThreadDemo2

package org.example.bk.multithread;public class ThreadDemo2 {public static void main(String[] args) {TicketWindow tw = new TicketWindow();Thread t1 = new Thread(tw,"窗口1");Thread t2 = new Thread(tw,"窗口2");t1.start();t2.start();}
}class TicketWindow extends Thread {private int tickets = 5;public void run() {while (tickets > 0) { Thread th = Thread.currentThread(); // 获取当前线程String th_name = th.getName(); // 获取当前线程的名字System.out.println(th_name + " 正在发售第 " + tickets-- + " 张票 ");}}
}

运行结果

 从结果看到Thread方式可以"不重复卖票"。因为只new TicketWindow对象1次。

RunnableDemo2

package org.example.bk.multithread;public class ThreadDemo02 {public static void main(String[] args) {TicketWindow1 tw1 = new TicketWindow1();TicketWindow1 tw2 = new TicketWindow1();Thread t1 = new Thread(tw1,"窗口1");Thread t2 = new Thread(tw2,"窗口2");t1.start();t2.start();}
}class TicketWindow1 implements Runnable {private int tickets = 5;public void run() {while (tickets > 0) {Thread th = Thread.currentThread(); // 获取当前线程String th_name = th.getName(); // 获取当前线程的名字System.out.println(th_name + " 正在发售第 " + tickets-- + " 张票 ");}}
}

运行结果

 从运行结果看,Runnable也可以实现"重复卖票",因为new TicketWindow1对象2次。

综上所述

"重不重复卖票"现象并不是Thread和Runnable的不同造成的,而是由于创建线程的方式不同造成的。

完成!enjoy it!

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

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

相关文章

【Pytorch】learning notes

文章目录【torch.xxx】torch.addmm() / torch.addmm_()torch.clamp() / torch.clamp_()torch.eq() / torch.ne()torch.manual_seed()torch.unique()torch.save() / torch.load()torch.view() / torch.permute() / torch. transpose() / torch.reshape()【torch.cuda.xxx】torch…

可以替代911s5的这几款产品还有跨境人士不知道吗?

不久前跨境电商用户都收到的坏消息无疑就是:911s5正式宣布停止运营并永久关闭。对于911s5,相信几乎所有的跨境电商用户都知道,因为其低廉的价格一直很受欢迎。所以一时间大家纷纷寻找911s5的替代品,但不是那么容易找的。今天这篇文…

投资组合图形化:EAP.util.plot

实证资产定价(Empirical asset pricing)已经发布于Github和Pypi. 包的具体用法(Documentation)博主将会陆续在CSDN中详细介绍,也可以通过Pypi直接查看。 Pypi: pip install --upgrade EAP HomePage: EAP a catchy description …

38 字典名[键名]=值 向字典增加键值对

38 字典名[键名]值 向字典增加键值对 文章目录38 字典名[键名]值 向字典增加键值对1. 语法2. 代码示例1. 字典中有要操作的键名—作用为修改2. 字典中没有要操作的键名—作用是增加3. 课后练习4. 列表增加元素知识回顾5. 总结1. 语法 向字典中增加键值对和修改字典的值的语法结…

开箱即用的数据缓存服务|EMQX Cloud 影子服务应用场景解析

在物联网业务高速迭代的今天,快速连接物联网设备与平台应用,实现业务快速落地与市场验证,是很多企业塑造核心竞争力、实现业务创新的关键。 EMQX Cloud 作为一站式运维代管的 MQTT 消息云服务,可以帮助用户在公有云环境中快速实现…

JavaScript:模拟拍照

实现拍照功能需要使用电脑的摄像头,可以使用 navigator.mediaDevices.getUserMedia() 方法,传递相应的参数就能开启摄像头 navigator.mediaDevices 是一个媒体设备对象,通过 getUserMedia( )方法开启音频和视频媒体设备。 getUserMedia 参数…

文献阅读-融合注意力机制的 IETM 细粒度跨模态检索算法

引用格式:翟一琛,顾佼佼,宗富强,姜文志.融合注意力机制的 IETM 细粒度跨模态 检索算法[J/OL].系统工程与电子技术. https://kns.cnki.net/kcms/detail/11.2422.TN.20220823.1030.004.html 期刊&#xff1a…

跟李沐学AI-动手学深度学习1

整体内容 神经网络可以理解为是一种语言 数学和代码的结合,道术结合,关键在动手 是什么,怎么做,为什么这样 发展知识和应用 广告点击预测三个步骤 预测和训练 模型控制广告展现 数据格式 0维,1维&#xff0c…

【仿牛客网笔记】初识Spring Boot,开发社区首页-MyBatis入门

安装MySQL Server 安装MySQL Workbench 安装过程略。。。 Mybatis手册 Mybatis整合 Mybatis的核心组件: SqlSessionFactory:用于创建SqlSessionFactory工厂类。 SqlSession:Mybatis的核心组件,用于数据库执行SQL 主配置文件:XM…

大一学生期末大作业 html+css+javascript网页设计实例【电影购票项目】html网页制作成品代码

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,有div的样式格局,这个实例比较全面,有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 文章目录一、网页介绍一…

java面试题总结-1

Java语言特点 (1)简单易学、有丰富的类库 (2)面向对象(java最重要的特性,让程序耦合度更低,内聚性更高) (3)与平台无关性(JVM是Java跨平台使用的…

拦截器和过滤器

拦截器和过滤器 参考: 过滤器和拦截器的区别_至今没搞明白的博客-CSDN博客_过滤器和拦截器的区别 拦截器与过滤器的区别_℡tang的博客-CSDN博客_拦截器和过滤器的区别 文章目录拦截器和过滤器过滤器概念作用Filter链与Filter生命周期SpringBoot 实现过滤器方式一…

如何将各大网盘整合到一起顺便挂载本地使用(文末附软件获取方式)

目录 1、Alist.exe 2、RaiDrive 今天发现了一个网盘变硬盘神器,它不仅安全免费,更全面支持:百度网盘、阿里云盘、天翼云盘、蓝奏云、闪电盘、夸克网盘、迅雷网盘、等众多你们听过,以及没有听过的所有网盘! 直接先看效…

Mac环境下反编译工具的使用

日常工作中避免不了反编译工具经常安装(换电脑设备、手滑把文件夹删除了。。。等等原因),而且时间一久忘记命令的使用,因此做下记录。 一、反编译工具三件套 apktool:获取apk里的资源文件、配置文件、清单文件、lib文…

毕业论文中引用方法、原理、定义等 如何降重才更有效果?

论文重复率过高是一件很痛苦的事,我当年的本科论文,一共查了四遍才过。 我的查重方法其实比较简单,初稿出来以后我就开始查重了,然后按照标注把标红的部分全部修改掉,而后以此类推,每次改外,或…

BIM+物联网应用,可以解决生活中的诸多问题?

hi,还是我,建模助手。 本期的头条我们聊过有关于元宇宙、BIM和智慧城市之间的些许关联。顺着这条线,再和大家说说更深入的东西——物联网。 它与BIM的结合,可以解决生活中的哪些问题。 01 物联网与BIM关系 在建筑走向智能的时代&a…

ProGAN 论文精读

作者:Tero Karras, Timo Aila, Samuli Laine, Jaakko Lehtinen单位:NVIDIA发表期刊:ICLR 2018 一、前期知识储备: 1.1DCGAN: 1.1.1模型结构: 1.1.2项目地址: github git clone https://git…

【附源码】计算机毕业设计SSM数据分析教学网站

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

微信公众号搭建查题系统

微信公众号搭建查题系统 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 查题校园题库:查题校园题库后台(…

Go Machine Learning

Go Machine Learning 前言 最近因为一直在弄部署整天c写的非常头疼,趁着昨天把分割部署写好后打算换换口味,想着试试Go语言来实现一些机器学习,深度学习会是什么样子.之前推荐过Go(goplus),不过这次打算用更基础的go语法来尝试. 1.准备工作 对于某个从未涉及的领域一开始肯…