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

2023-11-04

一、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里,如下:
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中的多线程、同步代码块、同步方法、锁 的相关文章

  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • 如何将本机库链接到 IntelliJ 中的 jar?

    我正在尝试在 IntelliJ 中设置 OpenCV 但是我一直在弄清楚如何告诉 IntelliJ 在哪里可以找到本机库位置 在 Eclipse 中 添加 jar 后 您可以在 Build Config 屏幕中设置 Native 库的位置
  • 序列的排列?

    我有具体数量的数字 现在我想以某种方式显示这个序列的所有可能的排列 例如 如果数字数量为3 我想显示 0 0 0 0 0 1 0 0 2 0 1 0 0 1 1 0 1 2 0 2 0 0 2 1 0 2 2 1 0 0 1 0 1 1 0
  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • 如何循环遍历所有组合,例如48 选择 5 [重复]

    这个问题在这里已经有答案了 可能的重复 如何在java中从大小为n的集合中迭代生成k个元素子集 https stackoverflow com questions 4504974 how to iteratively generate k
  • 使用 LinkedList 实现下一个和上一个按钮

    这可能是一个愚蠢的问题 但我很难思考清楚 我编写了一个使用 LinkedList 来移动加载的 MIDI 乐器的方法 我想制作一个下一个和一个上一个按钮 以便每次单击该按钮时都会遍历 LinkedList 如果我硬编码itr next or
  • 如何使用assertEquals 和 Epsilon 在 JUnit 中断言两个双精度数?

    不推荐使用双打的assertEquals 我发现应该使用带有Epsilon的形式 这是因为双打不可能100 严格 但无论如何我需要比较两个双打 预期结果和实际结果 但我不知道该怎么做 目前我的测试如下 Test public void te
  • 过滤两次 Lambda Java

    我有一个清单如下 1 2 3 4 5 6 7 和 预期结果必须是 1 2 3 4 5 6 7 我知道怎么做才能到7点 我的结果 1 2 3 4 5 6 我也想知道如何输入 7 我添加了i gt i objList size 1到我的过滤器
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐

  • 用Python搭建2层神经网络实现mnist手写数字分类

    这是一个用python搭建2层NN 一个隐藏层 识别mnist手写数据集的示例 mnist py文件提供了mnist数据集 6万张训练图 1万张测试图 的在线下载 每张图片是 28 28 28 28 28 28的尺寸 拉长为 1
  • windows安装MSYS2(mingw && gcc)

    一 简介 本文主要介绍如何在windows环境下安装msys环境 二 软件安装步骤 2 1 官网下载 msys官网链接 https www msys2 org 下载完成 2 2 软件安装 根据网页提示选择需要安装的目录 并等待安装完成 安装
  • 区间预测

    区间预测 MATLAB实现QRLSTM长短期记忆神经网络分位数回归多输入单输出区间预测 目录 区间预测 MATLAB实现QRLSTM长短期记忆神经网络分位数回归多输入单输出区间预测 效果一览 基本介绍 模型描述 程序设计 参考资料 效果一览
  • 【小程序】如何实现一个可折叠的列表

    作者刚接触小程序开发不久 打算用 CSDN 把学习过程中遇到的一些问题记录下来 都是一些浅显易懂的内容 希望对你也有所帮助 如文章标题所示 作者要实现一个可折叠的列表 先来看一下页面效果 这种展示方式的实现非常简单 话不多话 直接上代码 首
  • 用EasySysprep封装Win7系统

    前面我介绍了使用Dism 封装Windows 7系统 不过最后还是没达到我想要的效果 不过经过一番查阅之后 我发现我想要的效果好像没办法简单的使用单一工具达到 我希望做成的效果是类似于Win10 一个ISO镜像内置各种驱动及最新的更新 安装
  • Image size of 512922x322 pixels is too large. It must be less than 2^16 in each direction

    plt figure figsize 10 8 sns regplot x data num y data y marker o ci 95 scatter kws color b alpha 0 2 s 3 fit reg False 线
  • iOS开发环境xcode搭建

    1 到 https developer apple com download 或者在APP store下载 2 下载完成后会在launchpad显示 点击安装
  • python计算机视觉- 相机模型与参数标定

    文章目录 相机投影模型 针孔相机模型 像主点偏移 内参矩阵 畸变现象 畸变矫正 外参矩阵 两类参数 相机标定 线性回归 最小二乘 非线性优化 标定过程 实验过程 MATLAB进行标定 相机投影模型 针孔相机模型 针孔照相机模型是计算机视觉中
  • 我以前的博客在ITEYE上

    我以前的博客 https www iteye com blog user jiasudu 这个是我以前的博客 密码忘记了 就不搬家了 大家可以去看看 主要是十多来年记录ofbiz的资源 可以说是大全
  • 第九站:速学JavaScript中的函数

    js函数 欢迎来到 JavaWeb的奇妙冒险 教学系列 在本站中 我们将深入探索Web开发的精彩世界 在学习的过程中 我们既要保持轻松愉快 又要确保高质量的教学内容 准备好进入第九站的学习之旅了吗 让我们开始吧 文章目录 js函数 介绍 定
  • IDEA 登陆Gitee账户登录不上解决方案

    Mark一个IDEA2021 1连接gitee的bug 点击VCS想要share on Gitee时出现idea loading information for gitee窗口 然后始终连接不上Gitee 可能的解决方案 检查自己的Gite
  • [报错解决]name 'keras_applications' is not defined

    加载模型报错 解决方案 pip install keras applications 1 0 4 no deps pip install keras preprocessing 1 0 2 no deps pip install h5py
  • Python脚本批量造数据、跑定时任务协助测试

    目录 批量造数据 结合python pytest fixture 实现定时任务接口调用 目录结构 定时任务 批量造数据 连接Mysql的信息 1 import pymysql 2 数据库连接信息 3 多个库要有多个conn 4 conn p
  • CVE-2022-23222 Linux Kernel ebpf 权限提升漏洞

    漏洞背景和描述 eBPF extended Berkeley Packet Filter 是一种可以在 Linux 内核中运行用户编写的程序 而不需要修改内核代码或加载内核模块的技术 简单来说eBPF 让 Linux 内核变得可编程化了 由
  • 零基础学习WEB前端开发(六):HTML超链接标签

    一 超链接 二 用法及分类 基本语法 外部链接 内部链接 空连接 下载链接 其他元素链接 锚点链接 一 超链接 HTML使用标签 a 来设置超文本链接 超链接可以是一个字 一个词 或者一组词 也可以是一幅图像 您可以点击这些内容来跳转到新的
  • Generated Knowledge Prompting for Commonsense Reasoning

    本文是知识图谱系列相关的文章 针对 Generated Knowledge Prompting for Commonsense Reasoning 的翻译 常识推理的生成知识提示 摘要 1 引言 2 生成知识提示 3 实验设置 4 实验结果
  • 一个自动将状态机生成代码的软件

    如果你是一个程序员 对状态机应该有一定的了解 甚至会经常使用 使用状态机的时候 一般都是自己设计程序去实现状态机 但 当要维护代码时 就会显得不方便 特别是比较复杂的时候 我幻想着有一个软件 能在图形界面上设计状态图 然后自动生成C C 代
  • 都掏出来了,大学四年珍藏的26个宝藏网站,全部整理好给大家!!!

    文章目录 前言 哔哩哔哩 慕课网 编程学习网站 菜鸟教程 W3cSchool 刷题网站 力扣 牛客网 在线编程模块 CodeTop 赛码网 蓝桥杯ACM刷题网站 实用工具 Processon ioDraw 在线JSON解析 在线进制转换 博
  • Verilog状态机

    状态机定义 有限状态机 Finite State Machine 表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型 有限状态机是指输出取决于过去输入部分和当前输入部分的时序逻辑电路 一般来说 除了输入部分和输出部分外 有限状态机
  • java中的多线程、同步代码块、同步方法、锁

    一 java中实现多线程的三种方式 1 继承Thread类的方式进行实现 2 实现Runnable接口的方式进行实现 3 利用Callable接口和Future接口方式实现 1 继承Thread类的方式进行实现 步骤 自定义一个类继承Thr