java中的多线程、同步代码块、同步方法、锁

news2024/11/27 8:40:49

一、java中实现多线程的三种方式
(1)继承Thread类的方式进行实现;
(2)实现Runnable接口的方式进行实现;
(3)利用Callable接口和Future接口方式实现。
1.继承Thread类的方式进行实现
步骤:
自定义一个类继承Thread;重写run()方法,run()方法中写的是想要线程执行的代码;创建子类的对象,并启动线程。
例如:
这里使用线程的getName()方法和setName()方法对线程进行区分。
在这里插入图片描述
在这里插入图片描述
2.实现Runnable接口的方式进行实现
自己定义一个类实现Runnable接口;重写里面的run()方法;创建子类的对象;创建一个Thread类的对象并开启线程。
例如:
在这里插入图片描述
在这里插入图片描述
说明:上述代码中实现了Runnable接口的类是放在了新建的Thread类中的,可以理解为实现了Runnable接口的类里面是线程要执行的任务,将任务交给执行线程。还需要注意,为了区分线程,需要给线程取名setName(),但是在实现了Runnable接口的类的run()方法不能直接使用getName()来获取线程名字,它是Thread类中的方法,解决方式是使用Thread的静态方法currentThread()来获取执行run()的当前线程,然后再使用getName()方法。
应用场景:你可能会觉得Runnable很麻烦,但要注意,java中继承只有一个父类,而实现接口可以多个,且实现接口也可以继承,所以当有继承的类想要实现多线程时就可以使用Runnable。
3.利用Callable接口和Future接口方式实现
可以发现前两种线程的实现方式中,run()都没有返回值,不能获取线程执行的结果。
步骤:创建一个类实现Callable接口;重写call(),该方法有返回值,返回线程运行的结果;创建实现Callable接口的类的对象(表示多线程要执行的任务);创建FutureTask的对象(管理多线程执行的结果);创建Thread类的对象并启动。
例如:
在这里插入图片描述
说明:上图中Callable的泛型中指定的数据类型是重写的call()的返回值类型。
在这里插入图片描述
说明:上面定义的是FutureTask的对象,通过泛型指定管理的返回值结果的类型。实现Callable接口的类可以看成指定任务,将其对象作为FutureTask对象的构造器参数,再将FutureTask对象给Thread对象的构造器参数,最后通过Thread对象来开启线程,而获取线程的执行结果是通过FutureTask对象获得。

二、Thread常用的成员方法
在这里插入图片描述
说明:线程的优先级越高,抢占到cpu的概率越大。
1.getName()和setName()
getName()和setName()在之前的代码中演示过了。需要注意的是
(1)如果没有用使用setName()为线程设置名字,使用getName()会获取线程默认的名字,格式为:Thread-x(x=0,1,…)。
(2)除了通过setName()的方式为线程设置名字之外,还可以在新建Thread对象时为线程设置名字。
在这里插入图片描述
如果使用继承了Thread的类,需要重写父类的构造方法(子类不继承父类的构造方法)。
例如:
在这里插入图片描述
在这里插入图片描述
2.Thread.currentThread()
前面使用过了。
注意:在main方法中使用Thread.currentThread().getName()后打印方法返回值可以发现值为“name”,在JVM虚拟机启动后,会自动启动多条线程,其中一条线程叫做main线程,它的作用就是调用main方法,执行里面的代码。
3.sleep()
方法说明:
线程执行到这个方法会停留对应的时间(由参数指定,单位为毫秒,1秒=1000毫秒),当时间到了之后,线程会自动地醒来,继续执行后续代码。
例如,下图中的代码的效果为先输出11111,等待5秒后再输出00000:
在这里插入图片描述
4.setPriority()和getPriority()
设置和获取线程的优先级的方法。注意,线程的优先级默认为5,最小为1,最大为10。
例如:
在这里插入图片描述
在这里插入图片描述
注意:线程的优先级并不说明一定率先占用cpu先执行完,只是概率更高。
5.setDaemon()与守护线程
守护线程即备胎线程,当其他的非守护线程执行完毕后,守护线程也会陆续结束。
例如,对设置线程优先级的代码进行改写:
在这里插入图片描述
可以看到执行结果,当“飞机”线程结束后,“备胎线程”也会慢慢结束,还没有输出到99就结束了。
6.yield()和出让线程
Thread().yield()让出cpu,注意只是出让,之后还是会去再抢夺。
7.join()和插入线程
yield()和join()用的少,不过多说明。
三、同步代码块
同步代码块:把操作共享数据的代码锁起来。
格式:
synchronized(锁){
操作共享数据的代码
}
锁对象需要是唯一的,用static关键字修饰即可。
特点:
(1)锁默认打开,有一个线程进去了,锁自动关闭;
(2)里面的代码全部执行完毕,线程出来,锁自动打开。
例如,在不使用同步代码块的情况下,一个3个窗口同时贩票的情况下:
在这里插入图片描述
在这里插入图片描述
可以看到贩票不按顺序,且有的票重复,有的没有,这里涉及相同的同步机制就不过多解释。
使用java中的同步代码块机制。
在这里插入图片描述
上图中圈出的部分即为同步代码块(将其置于synchroized()后的花括号中,obj为锁,可任意设置,只要有static修饰)不同线程执行该代码块时其他线程不能执行。
执行结果如下:
在这里插入图片描述
补充,锁一般使用当前类的字节码对象,是唯一的:
在这里插入图片描述
补充一个小细节:不同区域的同步代码块的锁相同,也只能有一个线程执行,不能分别进入不同区域。
例如:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上例中,两个继承Thread类的子类中的同步代码块用了同一把锁,此时会发现,只能是一个一个线程执行完run()方法里的内容后,另一个线程才能执行run()里的内容。
而如果无锁则两个区域的代码并发执行:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
说明:
就是想说明一把锁不仅可以锁住同一个代码区,还可以一起锁住多个代码区。

四、同步方法
同步方法是指被synchronized关键字修饰的方法。
格式:
在这里插入图片描述
特点:
(1)同步方法是锁在方法里面所有的代码;
(2)锁对象不能自己指定。java已经规定好,非静态的方法锁对象是自身所在类,静态的同步方法的锁对象是所在类的字节码文件对象。
例如:
在这里插入图片描述
说明:这里要注意一下,使用实现Runnable的类来为线程设置任务时,ticket不用设置为静态变量,因为在下图中的代码中将实现Runnable的类的一个对象分别给了不同的Thread对象。
在这里插入图片描述
补充:StringBuilder和StringBuffer的不同之处就在于StringBuilder是线程不安全的,它的成员方法都没有synchronized关键字修饰,而StringBuffer是线程安全的,它的成员方法都由synchronized关键字修饰。
五、锁
jdk5之后提供了一个锁接口Lock,实现了比使用synchronized方法和语句更广泛的锁定操作,提供了手动获得锁和释放锁的方法。注意Lock是接口不能直接实例化,要通过它的实现类ReentrantLock来进行操作。
例如:

在这里插入图片描述
在这里插入图片描述
注意:上图中的代码有一个问题,就是程序一直运行没有终止,原因是当有一个线程进入同步块上锁后,当ticket==201时(票售罄),此时直接执行break;语句跳出循环,没有释放锁,而其他两个线程还处于while()循环中等着上锁,一直没有终止。解决方法是将释放锁的语句放到try-catch-finally的finally里,如下:
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【性能优化】性能优化

❤️ Author: 老九 ☕️ 个人博客:老九的CSDN博客 🙏 个人名言:不可控之事 乐观面对 😍 系列专栏: 文章目录 性能优化运行效率![在这里插入图片描述](https://img-blog.csdnimg.cn/557680b0ca51484c9c2c6c2…

金升阳|三极管的开关速度如何提高?

​三极管是一种常见的电子器件,广泛应用于电路中。它的开关速度是指从关断到导通或从导通到关断的转换速度。提高三极管的开关速度可以提高电路的响应速度,从而提高系统的性能。本文将介绍一些常见的方法来提高三极管的开关速度。 一、选择合适的三极管 …

华为组播实验pim-dm

组播源配置: R1: [r1]dis current-configuration [V200R003C00] sysname r1 snmp-agent local-engineid 800007DB03000000000000 snmp-agent clock timezone China-Standard-Time minus 08:00:00 portal local-server load flash:/portalpage.zip drop illegal-mac…

2023年软件测试有前途吗?技术变革,测试人的进阶发展路线...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 软件测试行业是否…

瑞吉项目优化

Redis缓存菜品 动态构造key。客户端传来的分类id作为key。从redis中获取缓存的数据。根据分类Id,使用redisTemplate.opsForValue().get 方法获取缓存的数据。如果缓存数据存在,直接返回,无需访问数据库。如果不存在,需要查询数据…

Redis从入门到精通【高阶篇】之底层数据结构整数集(IntSet)详解

文章目录 0.前言1.IntSet基本详解1.1 整数集的压缩算法原理1.2 整数集编码方式选择原理1.2.1 判断逻辑1.2.2 举例说明 2. 源码解析2.1. intsetNew2.2. intsetAdd2.3. intsetRemove2.4. intsetFind2.5. intsetUpgradeAndAdd2.6 收获 3.总结4.思考题5. Redis从入门到精通系列文章…

【MySQL 数据库的命令操作】

目录 一、数据库的基本概念二、数据库的发展三、主流的数据库介绍五、关系数据库1、数据库的解释2、数据库的管理3、常用的数据类型4、常见的数据库结构5、SQL语句 四、MySQL 安装方法1、安装Mysql环境依赖包2、创建运行用户3、编译安装4.创建mysql用户5.修改mysql 配置文件6、…

手动将第三方资源加IOC容器中

说明:在SpringBoot中,我们可以通过在各层类上加注解(Mapper、Service等)声明Bean对象,在需要使用时,可直接使用AutoWirted注解自动装配。但如果是使用第三方依赖中的对象,因为源码不能修改&…

04 类图

类图 定义 类图显示了类(及其接口)、类的内部结构以及与其他类的联系,是面向对象分析和设计所得到的最重要的模型。 作用:可视化地表达系统的静态结构模型 类之间的几种关系:泛化(Generalization)、实现(…

多元回归预测 | Matlab海洋捕食者算法(MPA)优化核极限学习机回归预测,MPA-KELM回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab海洋捕食者算法(MPA)优化核极限学习机回归预测,MPA-KELM回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% …

Jenkins部署及使用

Jenkins 1.定义 1.Jenkins是一款开源CI/CD软件,用于自动化各种任务,包括构建、测试和部署软件 1.CI/CD 1.CI:持续集成(Continuous Integration) 1.协同开发是目前主流的开发方式,一般由多位开发人员同时处理同一个应用的不同模块…

vue07---elementui使用/

elementui使用 cnpm isntall -S element-ui2.9 <template><div><h1>按钮的使用</h1><el-button-group><el-button type"primary" icon"el-icon-edit"></el-button><el-button type"primary" icon&…

《实战AI低代码》生成式AI和低代码开发的融合对组织效率的影响

目录 1. 自动化重复任务: 2. 智能流程优化: 3. 增强公民开发者: 4. 快速原型设计和实验: 5. 智能应用程序维护和更新: 随着科技的不断发展,生成式人工智能(AI)和低代码软件的融合已经成为了一个热门话题。这两种技术的结合可以加速创新并改变组织运作的方式。在本…

性能测试-平均事务响应时间ART分析解析,要卷就卷成最强的...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 业务背景&#xf…

5.基于图神经网络的点云分类

目录 一、数据处理二、点云生成三、PointNet阶段1&#xff1a;通过动态图生成进行分组阶段2&#xff1a;邻居聚合 四、网络架构五、训练程序 在本教程中&#xff0c;您将学习使用图神经网络进行点云分类的基本工具。在这里&#xff0c;我们得到了一个对象或点集的数据集&#x…

北京大学研发基于机器学习的多能干细胞分化系统,高效、稳定制备功能性细胞

内容一览&#xff1a;20 世纪以来&#xff0c;干细胞与再生医学技术一直是国际生物医学领域的热点前沿之一。现如今&#xff0c;研究人员已开始探索将干细胞转变为特定类型细胞。然而&#xff0c;这一过程中干细胞会出现不规则生长或自发分化为不同类型细胞的情况&#xff0c;因…

大数据治理:数据安全

数据安全 (Data Security)一般指保护重要的、机密的纸质信息或数字信息&#xff0c;防止未经授权的非法访问、泄露、篡改、丢失、损坏、数据滥用等情形。数据安全涵盖的范围非常广泛&#xff0c;包括存储数据的硬件设备、访问数据的软件环境、访问权限控制、相关的规章制度等。…

vscode配置clangd和clang-format

vscode安装和配置 如何安装和配置vscode以搭建c开发环境&#xff0c;可以查看我的另一篇博客&#xff1a;Windows上最轻量的vscode-C开发环境搭建。 在这篇博客中&#xff0c;详细介绍了如何安装vscode以及应该安装哪些插件。这里不再赘述。 vscode中想使用clangd来作为语言…

Unity极坐标Shader特效,以及使用Instanced Property实现相同材质不同参数

Unity极坐标特效 先看看效果 Unity极坐标Shader特效 有时候我们需要在场景中摆放一些热点&#xff0c;用户点击之后出现互动&#xff0c;当然实现这个功能的方法有很多&#xff0c;作为一名程序员&#xff0c;当然是要用最简单的实现。用shader程序化实现它。 啥是极坐标 极坐…

鲸落送书第二期清华出版社系列丛书

1.《Node.js从基础到项目实践&#xff08;视频教学版)》 《Node.js从基础到项目实践&#xff08;视频教学版&#xff09;》以理论结合实践的形式&#xff0c;讲解了Node.js 基础、框架、进阶知识和项目实践。本书为视频教学版&#xff0c;每一章节都有相对应的视频讲解&#xf…