当前位置: 首页 > news >正文

5.多线程学习

作者:爱塔居

专栏:JavaEE

作者简介:大三学生,喜欢总结与分享~

文章目录

目录

文章目录

章节回顾

一、wait 和notify

二、设计模式

2.1 单例模式


章节回顾

线程安全

1.一个线程不安全的案例(两个线程各自自增5w次,结果不是10w)

2.线程不安全的原因

(1)抢占式执行,随机调度。线程中的代码执行到任意一行,都随意可能被切换出去。

(2)多个线程同时修改同一个变量。

(3)修改操作不是原子的。

(4)内存可见性(volatile)编译器可能会对我们的代码进行优化。

一个线程频繁读,一个线程修改

(5)指令重排序。

除了这些原因,还有其他原因。

3.解决方案  加锁

在线程1加锁的过程中,线程2无法把自己的指令插入到线程1的修改过程中。

synchronized指定一个“锁对象”

4.volatile

关于volatile和内存可见性补充

内存可见性:

t1频繁读取主内存,效率比较低,就被优化成直接读自己的工作内存。

t2修改了主内存的结果,由于t1没有读主内存,导致修改不能被识别到。

工作内存=>CPU寄存器

主内存=>内存

工作内存和主内存都是由英文work memory和main memory翻译来的。所以,工作内存不一定非要是内存,可以是记忆,存储区,不一定是特指“内存条”。

这一套说法,也称为JMM(java memory model)

java是跨平台的。

1.兼容多种操作系统

2.兼容多种硬件设备

不同的硬件,其实差别很大。cpu和cpu之间,差别就会比较大。

像以前的cpu,上面只有寄存器。现在的cpu上面还有缓存。

而且有的cpu缓存还有好几个,L1,L2,L3,(现在常见的cpu都是3级缓存)

工作内存准确来说,代表cpu寄存器+缓存(CPU内部存储数据的空间)

 cpu读储存器速度比读内存快3-4个数量级。

 缓存读取速度介于寄存器和内存之间。

L1最快,空间最小(仍然比寄存器慢)

L3最快,空间最大(仍然比内存快很多)

实际上cpu尝试读一个内存数据:

1.先看寄存器里有没有

2.没有,看L1有没有

3.没有,看L2有没有

4.没有,看L3有没有

5.没有,看内存有没有

具体缓存的大小,对于程序效率的影响,也看实际的应用场景。


一、wait 和notify

线程的调度是无序的,随机的。但是,也是有一定的需求场景的,希望线程有序执行。

join是一种控制顺序的方式,但是功效有限。

wait就是让某个线程先暂停下来,等一等。

wait主要做三件事:

1.解锁

2.阻塞等待

3.当收到通知的时候,就唤醒,同时尝试重新获取锁。

notify就是把该线程唤醒,能够继续执行。

wait和notify是Object的方法

只要你是个类对象(不是内置类型/基本数据类型),都是可以使用wait和notify。

public class test {static int i;public static void main(String argv[]) throws InterruptedException{Object locker=new Object();Thread t1=new Thread(()->{while (true){try {System.out.println("wait 开始");synchronized (locker){locker.wait();}System.out.println("wait 结束");}catch (InterruptedException e){e.printStackTrace();}}});t1.start();Thread.sleep(1000);Thread t2=new Thread(()->{synchronized (locker){System.out.println("notify 开始");locker.notify();System.out.println("notify 结束");}});t2.start();}
}

 使用外套,阻塞等待会让线程进入WAITING状态。wait也提供了一个带参数的版本,参数指定的是最大等待时间。不带参数的wait是死等,带参数的wait就会等最大时间之后,还没有人通知,就自己唤醒自己。

wait会导致阻塞,竞争锁也会导致阻塞,两种不同的进入阻塞的方式。wait的初心就是为了实现阻塞的效果。

join只能是让t2的线程先执行完,再继续执行t1,一定是串行的

wait、notify,可以让t2执行完一部分,再让t1执行一部分,再让t2去执行,再……

唤醒操作,还有一个notifyAll。可以有多个线程,等待同一个对象。

比如在t1,t2,t3中都调用object.wait。此时在main中调用了object.notify 会随机唤醒上述的一个线程。(另外两个仍然会是waiting状态)

如果是调用了object.notifyAll,此时就会把上述三个线程都唤醒。伺候这三个线程就会重新竞争锁,然后依次执行。

总结:

1.wait需要搭配synchronized使用,sleep不需要。

2.wait是Object的方法,sleep是Thread的静态方法。

wait和sleep都是可以提前唤醒的。

他们最大的区别在于初心不同。

wait解决的是线程之间的顺序控制

sleep单纯是让当前线程休眠一会。

二、设计模式

设计模式,就是软件开发中的棋谱。大佬们针对一些常见场景,总结出来的代码的编写套路。设计模式有很多种。

在校招阶段,主要考察两个设计模式。

1.单例模式

2.工厂模式

设计模式需要大家有一定的开发经验的积累,才好理解。

2.1 单例模式

单例指的是单个实例(instance)对象。类的实例,就是对象。Java中的单例模式,借助java语法,保证某个类,只能够创建出一个实例,而不能new多次。

有些场景,本身就是要求某个概念是单例的。

//把这个类设定为单例
class Singleton{//唯一的实例的实体
private static Singleton instance=new Singleton();
//被static修饰,该属性是类的属性。JVM中,每个类的类对象只有唯一一份,类对象里的这个成员自然也是唯一一份了。
//获取到实例的方法public static Singleton getInstance(){return instance;}//禁止外部new实例private Singleton(){};
}
public class test {public static void main(String[] args) {Singleton s1=Singleton.getInstance();Singleton s2=Singleton.getInstance();}}

java中实现单例模式是有多种写法的。

主要说两种:

1.饿汉模式(急迫)

2.懒汉模式(从容)

A吃完饭立马洗碗(饿汉行为)

B吃完饭,不洗碗,等下一顿要用碗的时候,再洗碗。(懒汉行为)

通常认为,懒汉模式更好,效率更高。(非必要,不洗碗)

举一个计算机的例子:

打开一个硬盘上的文件,读取文件内容,并显示出来。

饿汉:把文件所有内容都读到内存中,并显示出来

懒汉:只把文件读一小部分,把当前的屏幕填充上,如果用户翻页,再读其他文件内容。

当文件特别大的时候,就可以看出懒汉模式的优势了。

饿汉模式:

//把这个类设定为单例,饿汉
class Singleton{//唯一的实例的实体
private static Singleton instance=new Singleton();
//被static修饰,该属性是类的属性。JVM中,每个类的类对象只有唯一一份,类对象里的这个成员自然也是唯一一份了。
//获取到实例的方法public static Singleton getInstance(){return instance;}//禁止外部new实例private Singleton(){};
}
public class test {public static void main(String[] args) {Singleton s1=Singleton.getInstance();Singleton s2=Singleton.getInstance();}}

懒汉模式:

//把这个类设定为单例模式中的懒汉模式。
class SingletonLazy{
private static SingletonLazy instance=null;public static SingletonLazy getInstance(){if(instance==null){instance=new SingletonLazy();}return instance;}private SingletonLazy(){};
}
public class test {public static void main(String[] args) {SingletonLazy s1=SingletonLazy.getInstance();SingletonLazy s2=SingletonLazy.getInstance();System.out.println(s1==s2);}}

 饿汉模式一开始就把实例创建好了,而懒汉模式是非必要不创建实例。

上述两个代码,是否是线程安全的?多个线程下调用getInstance,是否会出现问题?

饿汉模式,认为是线程安全的,只是读数据。

而在多线程下,懒汉模式可能无法保证创建对象的唯一性。

比如以下情况:

 如何解决上诉线程安全问题?

进行加锁,保证判定和new操作是原子性的。

//把这个类设定为单例模式中的懒汉模式。
class SingletonLazy{
private static SingletonLazy instance=null;synchronized public static SingletonLazy getInstance(){if(instance==null){instance=new SingletonLazy();}return instance;}private SingletonLazy(){};
}
public class test {public static void main(String[] args) {SingletonLazy s1=SingletonLazy.getInstance();SingletonLazy s2=SingletonLazy.getInstance();System.out.println(s1==s2);}}

相关文章:

5.多线程学习

作者:爱塔居 专栏:JavaEE 作者简介:大三学生,喜欢总结与分享~ 文章目录 目录 文章目录 章节回顾 一、wait 和notify 二、设计模式 2.1 单例模式 章节回顾 线程安全 1.一个线程不安全的案例(两个线程各自自增5w次&…...

数据结构中的堆

一、树的重要知识点 节点的度:一个节点含有的子树的个数称为该节点的度(有几个孩子)叶节点或终端节点:度为0的节点称为叶节点;如上图:B、C、H、I...等节点为叶节点(0个孩子)非终端节点或分支节点…...

Linux内核设备信息集合

本文结合设备信息集合的详细讲解来认识一下设备和驱动是如何绑定的。所谓设备信息集合,就是根据不同的外设寻找各自的外设信息,我们知道一个完整的开发板有 CPU 和各种控制器(如 I2C 控制器、SPI 控制器、DMA 控制器等)&#xff0…...

若依框架---权限管理设计

前言 若依权限管理包含两个部分:菜单权限 和 数据权限。菜单权限控制着我们可以执行哪些操作。数据权限控制着我们可以看到哪些数据。 菜单是一个概括性名称,可以细分为目录、菜单和按钮,以若依自身为例: 目录,就是页…...

Java设计模式(二)——工厂模式

当用户需要一个类的子类实例,且不希望与该类的子类形成耦合或者不知道该类有哪些子类可用时,可采用工厂模式;当用户需要系统提供多个对象,且希望和创建对象的类解耦时,可采用抽象工厂模式。 工厂模式一般分为简单工厂、…...

【Maven】

MavenMaven简介仓库坐标Maven项目构建依赖管理生命周期及插件插件模块拆分与开发聚合继承属性版本管理资源配置多环境开发配置跳过测试私服Maven简介 Maven的本质时一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM) POM(Project Object Model)&a…...

[JAVA]继承

目录 1.继承的概念 2.继承的语法 3.父类成员访问 3.1子类中访问父类成员变量 3.2子类中访问父类成员方法 4.super关键字 5.子类构造方法 6.继承方式 7.final关键字和类的关系 面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复…...

Vue3 pinia持久化存储(组合式Api案例演示)

pinia-plugin-persist( pinia持久化插件) 本文采用的是 组合式Api的方式来做Pinia的持久化存储演示 如果对pinia的持久化还是不是很了解的👨‍🎓|👩‍🎓,可以看一下笔者的上一篇文章…...

8个你一看就觉得很棒的Vue开发技巧

1.路由参数解耦 通常在组件中使用路由参数,大多数人会做以下事情。 export default {methods: {getParamsId() {return this.$route.params.id}} }在组件中使用 $route 会导致与其相应路由的高度耦合,通过将其限制为某些 URL 来限制组件的灵活性。 正…...

vue3+ts 开发效率提升

1、vite pnpm项目初始化 pnpm: 比npm或yarn快10倍 pnpm与其他包管理器(如npm和Yarn)的不同之处在于它使用一种称为“硬链接”的独特安装方法。当你使用PNPM安装一个包时,它并不会将包的文件复制到每个项目的node_modules目录中&a…...

【数据结构与算法】队列和栈的相互实现以及循环队列

目录🌔一.用队列实现栈🌙1.题目描述🌙2.思路分析🌙3.代码实现⛈二.用栈实现队列☔1.题目描述☔2.思路分析☔3.代码实现🌈三.实现循环队列🌔一.用队列实现栈 🌙1.题目描述 我们先看一下题目链接…...

mysql连接不上问题解决

公司新搭内网测试环境,mysql远程登录问题解决 远程登录: 1 修改host, mysql> select user,host,plugin from user; ---------------------------------------------------- | user | host | plugin | ------------------------…...

利用nginx实现动静分离的负载均衡集群实战

前言 大家好,我是沐风晓月,今天我们利用nginx来作为负载,实现两台apache服务器的动静分离集群实战; 本文收录于沐风晓月的专栏《linux基本功-系统服务实战》,更多内容可以关注我的博客: https://blog.csd…...

与chatGPT神聊,引领你深入浅出系统调用

在操作系统的教学中,系统调用的作用不言而喻,但是,对系统调用常常是雾里看花,似乎明白,又难以真正的触及,即使在代码中调用了系统调用,比如调用fork()创建进程&#xff0…...

自学大数据第十天~Hbase

随着数据量的增多,数据的类型也不像原来那样都是结构化数据,还有非结构化数据; Hbase时google 的bigtable的开源实现, BigtableHbase文件存储系统GFSHDFS海量数据处理MRMR协同管理服务chubbyzookeeper虽然有了HDFS和MR,但是对于数据的实时处理是比较困难的,没有办法应对数据的…...

vue更高效的工具-vite

目录 1.webpack 2.vite是什么 3.使用vite创建项目 4.最后总结 🐼webpack 简单来说,Webpack是一个打包工具。 站在2018年的角度,成为一个优秀的前端工程师,除了要会写页面样式和动态效果之外,还需要会用主流的单页…...

HFish蜜罐的介绍和简单测试(一)

目录 0、什么是蜜罐 0.1、蜜罐的定义 0.2、蜜罐的优势 0.3、蜜罐与情报 1、HFish介绍 1.1、设计理念 1.2、HFish架构 1.3、HFish特点 1.4、常见蜜罐场景 2、快速部署 2.1、环境要求 2.2、联网环境,一键安装 2.3、安装效果 3、错误排查 3.1、管理端问题…...

2023面试题汇总二

一、CSS面试题 1. 清除浮动的方式有哪些? 为什么要清除浮动?因为浮动的盒子脱离标准流,如果父盒子没有设置高度的话,下面的盒子就会撑上来。 额外标签法(在最后一个浮动标签后,新加一个标签,给其设置cle…...

C# 支付宝接口在线收款退款

收款 在C#中使用支付宝在线支付功能,需要使用支付宝开放平台提供的SDK(软件开发工具包),通过SDK中提供的API(应用程序接口)实现在线支付功能。 以下是使用C#实现支付宝在线支付的大致步骤: 获…...

python例程:《企业编码生成系统》程序

目录《企业编码生成系统》程序使用说明主要代码演示源码及说明文档下载路径《企业编码生成系统》程序使用说明 在PyCharm中运行《企业编码生成系统》即可进入如图1所示的系统主界面。在该界面中可以选择要使用功能对应的菜单进行不同的操作。在选择功能菜单时,只需…...

基于EB工具的TC3xx_MCAL配置开发04_ADC模块软件触发Demo配置

目录 1.概述2. EB配置2.1 添加HwUnit2.2 AdcPrescale配置2.3 添加ADC通道2.4 添加Adc Group2.5 Adc Group配置2.5.1 AdcGroup->General2.5.2 AdcGroup->AdcNotification2.5.3 AdcGroup->AdcGroupDefinition2.5.4 AdcGroup->AdcResRegDefinition2.6 中断配置1.概述 …...

内存操作函数

前言 🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍c语言中有关指针更深层的知识. 金句分享: ✨未来…...

免费搭建个人博客

免费搭建个人博客,并发布到公网 利用hexo搭建个人博客,通过gitee的pages发布到公网 1 前置准备 安装git、安装node.js(尽量选择长期支持的版本) node.js官网:https://nodejs.org/en/ git官网:https://git-scm.com/book/zh/v2 安装…...

【Vue全家桶】详解Vue Router(一)

【Vue全家桶】Vue Router详解(一) Vue系列文章目录: 内容参考链接Vue(一)【Vue全家桶】邂逅Vue、Vue的多种引入方式Vue(二)【Vue全家桶】声明式编程、MVVMVue(三)【Vue…...

9大 HIVE SQL 最频繁被问到的面试题

SQL是用于数据分析和数据处理的最重要的编程语言之一,因此与数据科学相关的工作(例如数据分析师、数据科学家和数据工程师)在面试时总会问到关于 SQL 的问题。 SQL面试问题旨在评估应聘者的技术和解决问题的能力。因此对于应聘者来说&#x…...

学大数据算跟风吗?

随着互联网、物联网和人工智能等技术的不断发展,大数据技术逐渐进入人们的视野,成为一个备受关注的热点话题。那么,大数据专业好学吗?前景如何?下面我们来一起探讨一下。 一、大数据专业的学习难度 大数据技术是一种综…...

[C#]关于ListBox的坑

在用C#写个Demo程序的时候,使用ListBox保存读取到的每行内容。然后在重复读取的时候需要清除ListBox中的内容,我看到ListBox有清除的函数:lsbFiles.Items.Clear();以为这个函数就可以解决所有的问题,但是....于是想了个方法准备一…...

Apache POI 入门·第一话

文章目录1 摘要2 Apache POI2.1 介绍2.2 应用场景2.3 入门案例2.3.1 将数据写入Excel文件2.3.1.1 导入POI maven坐标2.3.1.2 代码开发2.3.1.3 实现效果2.3.2 读取Excel文件中的数据2.3.3 实现效果2.4 开发案例——导出运营数据Excel报表2.4.1 产品原型2.4.2 接口设计2.4.3 代码…...

8个python自动化脚本提高打工人幸福感~比心~

人生苦短,我用Python 最近有许多打工人都找我说打工好难 每天都是执行许多重复的任务, 例如阅读新闻、发邮件、查看天气、打开书签、清理文件夹等等, 使用自动化脚本,就无需手动一次又一次地完成这些任务, 非常方便…...

【嵌入式烧录/刷写文件】-1-详解Motorola S-record(S19/SREC/mot/SX)格式文件

目录 1 什么是Motorola S-record 2 Motorola S-record的格式 2.1 Motorola S-record的结构 2.1.1 “Record type记录类型”的说明 2.1.2 “Record length记录长度”的说明 2.1.3 如何计算“Checksum校验和” 2.2 Record order记录顺序 2.3 Text line terminator文本行终…...

怎么做自己的网站教程/免费模板网站

Inject environment variables to the build process中设置环境变量: 1) 下载插件:Environment Injector 2) Jenkins项目配置变量: 构建环境 -> 勾选(Inject environment variables to the build proc…...

在网站上做教育直播平台多少钱/业务推广公司

在服务器上安装 zsh 和 oh-my-zsh 本身不是什么难的事情,不过因为国内网络环境的问题,很多东西总是事与愿违,然后公有云厂商也很少把方法贴出来,就很麻烦,反正搜官方文档也搜不太出来,除了自己做代理&#…...

外贸建站模版/企业网络营销策划书

三哥 内容来自【自学星球】 欢迎大家来了解我的星球,和星主(也就是我)一起学习 Java ,深入 Java 体系中的所有技术。我给自己定的时间是一年,无论结果如何,必定能给星球中的各位带来点东西。 想要了解更多&…...

wordpress微信群多个二维码/免费自助建站网站

概述 现在计算机网络的发展特点是规模不断扩大,复杂性不断增加!如何更有效地利用好企业IT资源,实现稳定的网络支持和网络效益一直是网络管理者备感棘手的问题。随着网络技术的飞速发展,越来越多的企业逐渐开始体验到了一种“成…...

网站项目建设策划方案/关键词挖掘方法

HTML方向 调用系统功能 使用<a>能快速调用移动设备的电话/短信/邮件三大通讯功能&#xff0c;使用<input>能快速调用移动设备的的图库/文件。 这些功能方便了页面与系统的交互&#xff0c;关键在于调用格式一定要准确&#xff0c;否则会被移动端浏览器忽略。 &…...

大型网站建设公司沈阳/网站优化费用报价明细

本章内容 自定义属性快速入门 外化配置 自动配置 自定义创建 Starter 组件 摘录&#xff1a;读书是读完这些文字还要好好用心去想想&#xff0c;写书也一样&#xff0c;做任何事也一样 图 2 第二章目录结构图 第 2 章 Spring Boot 配置 Spring Boot 配置&#xff0c;包括自…...