自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(34)
  • 收藏
  • 关注

原创 通过8种加锁情况来弄懂加锁对于线程执行顺序的影响

非静态同步方法使用的锁对象是this,也就是方法的调用者,而本案例中使用的是两个不同的资源类对象分别创建的线程,所以两个同步方法使用的锁对象是不一样的,第一个线程使用的锁对象是example1,第二个使用的是example2;上面的案例中谈到加锁并不能防止不需要锁或者需要其他锁的线程,所以虽然线程1先抢到了锁,但是在休眠的3s内CPU是线程2的,并且线程2需要获取的是另一把锁,这就使得线程2会比线程1先执行完。既然锁对象是同一个,并且线程1先抢到锁,那必然是线程1先执行,线程2后执行了。

2024-04-12 00:09:12 1056

原创 多线程学习-Lock锁以及监视器锁详解

我们知道使用同步方法或同步代码块会自动加锁和解锁,那有没有办法可以自己控制加锁和解锁的时机呢?java在JDK1.5之后提供了一个新的锁对象Lock,他有两个常用的方法lock和unlock,一个是手动加锁,另一个是手动解锁。但是Lock本身是一个接口不能实例化对象,通常我们在使用时需要用到它的一个实现类ReentrantLock来实例化对象。并且还能同时设置是否为公平锁。所谓公平锁和非公平锁,就是看加锁的过程是否公平,公平就是先来先加锁,非公平就是允许后来的线程插队,先获得锁。

2024-04-10 00:42:28 794

原创 多线程学习-等待唤醒机制

等待唤醒机制即通过wait和notify实现多线程之间的通信,进而实现多线程协同工作。

2024-04-07 23:36:05 736

原创 多线程学习-线程池

一个线程池所创建的线程分为核心线程和临时线程,核心线程则是在创建后会一直存在,直到线程池关闭,而临时线程则是当提交的任务过多时应急使用的,临时线程也会正常工作,但在工作结束后如果在一定时间内没有其他任务,则会被销毁。要注意的是,只有当等待队列的任务占满了整个队列,后面再提交任务时才会创建临时线程,并且创建的临时线程处理的任务并不是等待队列中的任务,而是队列满后后面再提交的任务。如果创建的临时线程达到最大数量,此时仍有任务被提交时就需要选择一种应对策略来处理后面提交的任务。

2024-04-05 23:30:24 2420 2

原创 多线程学习

什么是多线程有了多线程,我们就可以让程序同时做多件事情。多线程的作用充分利用程序运行的等待时间,让CPU在多个线程之间进行切换,从而提高程序的运行效率。多线程的用途只要是想让多个程序同时运行,就都会用到多线程。以游戏为例,游戏在加载页面不仅会加载资源,还需要加载背景、检查版本等,如果没有多线程,那就需要先加载资源,然后再进行其他操作,如果需要加载大量资源,那么需要等待很长时间才会进入下一步操作。

2024-04-05 01:14:58 1037

原创 多线程中常用的一些方法介绍

而java采用的是抢占式调度,多个线程需要进行竞争,谁能抢到CPU完全随机,只不过可以通过设置线程的优先级来提高随机到该线程的概率,注意只是提高了概率,并不是谁优先级高就一定先抢到;要注意的是,这个方法只能是让多线程运行的结果尽可能均匀,并不是绝对的,虽然出让了CPU的占用权,但出让后这个线程也可以再次竞争CPU的占用权,由于java使用的是抢占式调度,所以出让CPU后谁能抢到还是随机的,还是有可能出现尽管使用了yield方法还是有某个线程长时间连续执行的现象,通俗的讲就是“给你机会你不中用呀”。

2024-04-04 19:22:47 767

原创 多线程学习-线程安全

在执行输出操作时,需要先获取要输出的内容,此时读到的ticketnum是99,但还没有来得及执行println时间就耗尽了,此时线程1抢到了CPU,准备执行输出操作,获取到的ticketnum自然也是99,还没有来得及执行println,CPU就被线程3抢走了,线程3不仅执行了ticketnum++使其变为了100,还完整执行了输出操作,随后线程3进入100ms的休眠状态。此时线程2抢到了CPU执行输出操作,ticketnum的值还是3,所以线程2也会输出“正在售卖第3张票”,随后也进入100ms的休眠;

2024-04-04 19:15:38 720

原创 redis学习-redis配置文件解读

目录1.单位说明2. include配置3. network网络配置 3.1 bind绑定ip配置 3.2保护模式protected-mode配置 3.3端口号port配置​编辑 3.4超时断开连接timeout配置 4. general通用配置 4.1守护进程模式daemonize配置 4.2进程id存放文件pidfile配置 4.3日志级别loglevel配置 4.4日志文件命名logfile

2024-03-30 23:12:37 944

原创 redis学习-主从复制和哨兵模式

指的是将一台redis服务器中的数据复制到其他redis服务器,前者称为主机,后者称为从机,并且只能从主机复制数据到从机,从机不能复制给主机;主机主要负责写操作,从机则主要负责读操作,由于在日常应用中读操作频率较高,所以这样做可以减轻服务器的负担。数据冗余:将主机中的数据复制给从机实现了数据的热备份,是持久化之外的一种数据冗余方式。故障恢复:当主机出现故障时,可以利用从机中复制的数据实现快速的恢复。

2024-03-30 22:18:02 710

原创 redis学习-缓存穿透、缓存击穿、缓存雪崩

当用户在redis缓存中查询不到想要的信息时,会进入数据库中查询,此时如果同一时间有大量用户从redis中查询不到信息,就都会去数据库中查询,此时数据库就可能会因为压力过大而停止服务,这就是缓存穿透。是一种数据结构,对所有可能用到的参数以hash形式存储,当用户发起查询时会先在控制层进行校验,如果没有所请求信息的参数就不会进入数据库中查询,从而过滤掉这些对不存在信息的查询请求,减轻了数据库的压力。其中缓存服务器宕机造成的雪崩损失比较大,因为一旦宕机压力就都会转移到数据库上,这带来的风险是无法预知的。

2024-03-30 18:03:36 287

原创 redis学习-Hash类型相关命令及特殊情况分析

Hash的内部存储结构相当于一个map,存储的是一个个键值对;所以在redis中相当于Hash更适合存储一个对象,或者经常变动的信息。

2024-03-17 17:57:20 763

原创 redis学习-Zset集合类型相关命令及特殊情况分析

目录1. zadd key score1 value1 score2 value2 ...2. zrange key start end3. zrevrange key start end4. zrange key min max byscore5. zrangebyscore key min max6. zrevrangebyscore key max min7. zrem key value1 value2 ...8. zcard key9. zcount key min max Zs

2024-03-17 16:28:42 880

原创 redis学习-Set集合类型相关命令及特殊情况分析

接下来的所有类型的操作中,-1都代表最后。set集合是无序的且其中的值不允许重复,可以实现共同好友查找、随机数等。

2024-03-17 15:14:37 857

原创 redis学习-List类型相关命令以及特殊情况分析

接下来的所有类型的操作中,-1都代表最后。List采用链表的存储结构,可以将List当做栈或队列来使用。

2024-03-17 12:46:59 804

原创 redis学习-String类型的命令介绍以及特殊情况分析

接下来的所有类型的操作中,-1都代表最后。。创建键值对,当再次set已经存在的key时会覆盖掉之前的value;并且set可以将任意类型的数据转换成一个string类型的数据,比如对一个list类型的list1使用set list1 abc可以将list替换为string类型的abc。2. get key获取key对应的内容,仅对string类型的value使用。对指定key的value后添加其他信息,即对value的内容进行字符拼接;添加后会返回value的长度;

2024-03-17 12:17:32 917 1

原创 redis学习-redis介绍

redis即远程字典服务,是当下最热门的NoSQL(非关系型数据库)技术之一,采用KV键值对的数据结构存储数据,也被称之为结构化数据库。Redis会周期性地将更新的数据写入磁盘并将更新操作写入追加的记录文件,并在此基础上实现了主从同步。Redis是基于内存存储的,能够实现持久化,并且效率高,支持多种语言和多种数据类型,同时也支持集群、事务等。redis支持五种基本数据类型String、Set、Zset、Hash、List以及三种特殊类型Bitmaps、HyperLogLog、Geospatial。

2024-03-17 11:47:58 771 1

原创 JVM学习-JMM

JMM即Java内存模型 ,定义了一套在多线程读写共享数据(如数组、成员变量等)时,对数据的可见性、有序性、原子性的规则和保障。JMM和Java内存结构关系不大,内存结构就是JVM的内存组成、垃圾回收以及字节码和类加载的一些技术。CAS即Compare And Swap,是一种乐观锁的思想,不使用synchronized对共享变量加锁,通过volatile关键字的配合实现了无锁并发。

2024-03-16 19:28:22 2121 1

原创 JVM学习-JVM的自动优化

JVM会进行两部分的优化:一部分是编译时优化,也就是语法糖;另一部分是运行时优化。

2024-03-16 18:25:15 967 4

原创 JVM学习-类加载

第二种是使用系统变量jdbc.drivers定义的驱动类的类名加载驱动,调用Class.forName()方法加载和初始化驱动类,使用的是系统类加载器,也就是应用类加载器。静态变量的空间分配在准备阶段完成,而赋值则是在初始化阶段,但是final类型的静态变量比较特殊:如果是final的基本类型或字符串类型的静态变量,则分配空间和赋值都在准备阶段完成,因为对于这些类型的变量而言final说明值不会改变,已经确定了静态变量的值,所以在准备阶段会直接赋值;类加载分为三个阶段:加载、链接、初始化。

2024-03-16 16:46:49 1088 1

原创 JVM学习-底层字节码的执行过程

静态方法不需要对象来调用,直接调用即可,如果使用对象调用静态方法,那么在底层的字节码指令中会先让对象的引用入栈,准备进行方法调用时发现是一个静态方法,那么就会将这个对象的引用弹出,然后直接通过invokestatic调用静态方法,这就会多执行一次入栈和弹出操作。所以,如果将实现类换成Cat,那么所创建的对象的对象头中的类型指针指向的就是Cat.class,然后从Cat类的虚方法表中找到Cat的say方法地址进而去调用。倘若没有dup复制,那么在构造完成后就会将仅有的对象引用弹出,就无法赋给变量。

2024-03-15 23:41:25 869 1

原创 JVM学习-垃圾回收专题+GC调优

三个阶段循环进行:当伊甸园被占满时会触发垃圾回收,同时也会触发STW;幸存的对象会以复制的算法放到幸存区(对应示意图中E->S);当一个幸存区内存不足时则会再次触发垃圾回收,寿命达到阈值的会将其放入老年代中(对应示意图中S->O),其他寿命不足的则会复制到其他幸存区中(对应示意图中S->S)。新生代在垃圾回收时会进行初始标记,标记那些根对象,当老年代的内存占用达到阈值时,则会进行并发标记。并发标记完成后会先进行最终标记,类似于CMS的重新标记,也会触发STW;

2024-03-15 17:52:27 1131

原创 JVM学习-常量池、运行时常量池以及串池

intern方法在jdk1.8中是将这个字符串尝试放入串池,如果有则不会放入,如果没有则会放入串池,两种情况都会返回串池中的对象,所以由于s3已经将ab放入了串池导致s4放入串池失败,此时s4仍是堆中的对象(如果先执行s4再执行s3那么由于串池中没有ab就会将s4放入串池,此时s4就和s3一样都是串中的对象了),但由于返回的是串中的对象所以s6是串中的对象,s6==s3的结果是true。其次,串池是可以动态存放的而常量池是固定的,我们在创建字符串对象时如果串池中没有对应的值就会在串池中动态生成。

2024-03-15 00:49:21 1693 1

原创 JVM学习-JVM简介以及其内部结构

JVM是Java虚拟机的缩写,是Java程序的运行环境。更准确地说是Java程序的二进制字节码的运行环境,因为JVM的主要作用是将Java源码编译为字节码并执行。Java程序之所以能够跨平台运行就是因为JVM的存在,JVM编译后的字节码在任何支持JVM的平台都可以运行且无需再次编译;并且JVM有自己的垃圾回收机制,自动管理内存,减轻了程序员内存管理的负担。通过学习JVM,我们就可以了解一个Java程序在底层的执行过程,进而优化我们的代码。

2024-03-14 22:44:42 1212 1

原创 静态代码块

静态代码块在类加载的初始化阶段被执行,可用于确保在使用类时,相关的资源和变量已经被正确初始化,提高了代码的可维护性和可靠性。static {执行初始化的代码。

2024-03-07 22:56:49 372 1

原创 Spring Boot学习-给对象属性赋值的三种方式

首先准备两个类用于演示,Clothe和Person类,并加上Component注解,@Component是一个通用注解,表示将这个类标记为一个组件并放到Spring容器中,在Spring Boot运行时就会自动创建实例;

2024-03-06 00:34:45 754 2

原创 Spring Boot学习-什么是Spring Boot以及相关配置(包括图标)

Spring Boot是一个轻量级框架,可以快速、敏捷地开发一个基于Spring的应用程序,该框架默认帮我们做了很多配置,并且也集成了大量第三方库的配置,同时内嵌了Tomcat和Jetty(默认使用的是Tomcat),这就使得我们可以不用再过多关注配置的问题,只用专注于项目的开发就好了。但要注意的是,Spring Boot本身不提供Spring框架的两大核心功能,只是能够简便地构建一个无需专门配置的项目,在开发中仍需要结合Spring使用才能发挥更大效益。

2024-03-05 19:56:00 982 1

原创 Spring学习-AOP的含义及实现

所扩展的与原有业务模块相关联的功能就是横切关注点;实现这个扩展功能所需要的方法就是通知;这些方法若都归到一个类集中管理,那这个类就是切面;这些方法将来会被插入到原有的项目中,插入的位置就是切入点。

2024-03-03 01:35:37 982

原创 Spring学习-动态代理

我们可以先看静态代理,静态代理的优点和代理模式的优点相同,但缺点就是和业务层通过new指明实现类来实现一个Dao层接口的弊端一样:如果想用另一个实现类来实现同一个接口,就需要修改new的实现类的类型,这就会违背尽量不修改代码的开发原则;静态代理的代理类实现的是指定业务的接口,想要更换代理业务就需要重写一个代理类,这就需要改动大量代码,工作量太大。动态生成代理类的重点是怎样写一个能够动态生成代理类的工厂,这个工厂创建一个合格的代理类需要两部分:第一部分是能够动态生成代理类,即生产产品的外壳;

2024-03-01 04:16:55 1244 1

原创 Spring学习-静态代理

从以上的例子中不难看出,代理模式的优点首先就是可扩展性高,并且能够使得真实角色功能纯粹,不需要关系其他服务;其次就是真实角色只负责主要功能,扩展功能交由代理角色实现,分工明确;最后就是所有扩展的功能都由代理角色实现,使得扩展功能方便集中管理。这也是静态代理的优点。当然静态代理也有缺点,静态代理是一个真实角色对应一个代理角色,如果有多个真实角色就需要多个代理角色,会使得开发效率变低。比如租房需要租房中介,二手车需要二手车中介等,这就需要编写许多的中介代理,开发难度就变高了。

2024-02-29 23:31:38 350 1

原创 Spring学习-依赖注入(DI)

依赖注入是一种设计模式,当程序运行依赖其他对象时,不需要自己new一个对象,而是通过容器使得所依赖的对象在外部创建,然后注入到当前类中,这样就降低了耦合度,提高了代码的可复用和可维护性。

2024-02-29 19:08:38 335

原创 Spring学习-配置解读

最简单的用途就是将所有的xml文件合并为一个,这经常用于团队合作的项目,每个人分别设计不同的模块,对应的配置文件也不同,这就需要使用import将这些配置文件合并为一个作为整个项目的配置文件。name:给对象起一个或多个别名,多个别名之间可以用空格、逗号、分号等分隔符分隔 开。这个标签的作用是可以给创建的对象起一个别名,通过对象的id和这个别名都可以获取到这个对象。id:所创建对象的唯一标识名,相当于对象名。这是Spring本身默认配置的bean。

2024-02-29 16:38:01 345

原创 Spring学习-IOC容器怎样创建对象

通常我们在new一个对象时会调用这个类的构造器,即使我们在编写一个类时不写构造方法,系统也会生成一个默认的无参构造方法,这个无参构造方法实际上继承的是万类之父Object的无参构造方法,所以即使我们不写构造函数也能直接new创建。从运行结果可以看出,我们在获取对象之前就调用了两次构造函数,这就说明当我们在获得Spring的上下文对象时Spring就已经创建好了所有的对象,后面我们获取的时候直接拿就行了,这也就是为什么叫做容器的原因了。所以同一个id的对象Spring只会创建一个,每次获取的都是同一个对象。

2024-02-29 15:00:29 866

原创 Spring学习-什么是IOC

此时如果用户新增了一个需求,需要用UserDaoImpl1实现类来实现getUser()的方法,那就需要修改代码为 private UserDao userdao=new UserDaoImpl1(),如果需要用其他更多实现类来实现getUser()方法,那每次都要修改代码,这在实际开发中是极其麻烦的。在以上的例子中,创建hello对象并没有使用new,而是将对象交给Spring创建,用户需要什么对象就从Spring容器中get就好了,这就实现了IOC特性。而以上只是IOC的原型!首先定义Hello类。

2024-02-29 04:48:38 353

原创 Spring学习-初探Spring

Spring是一个轻量级且非侵入式的框架,所谓非侵入式就是集成Spring后不会对原有项目产生影响;且Spring拥有两大特性:控制反转(IOC)、面向切面编程(AOP),支持事务以及其他框架的整合。Spring Boot是一个快速开发的脚手架,基于Spring Boot可以快速开发一个微服务,只 需要注意约定大于配置。然后选取所需的版本,将对应的依赖包代码复制到pom.xml文件中。Spring旨在使现有的技术能够更加容易地被使用。

2024-02-29 01:59:59 334

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除