- 博客(54)
- 收藏
- 关注
原创 StringTable
文章目录一、String的基本特性不可变性一道面试题二、String的内存分配三、String的基本操作四、字符串拼接操作五、intern()的使用两种创建对象方式JDK6与JDK7/8对比一、String的基本特性String声明为final,不可被继承实现了Serializable接口,支持序列化;实现了Comparable接口,字符串可以比较大小在Java8及以前使用char[]存储字符串,在Java9后改用byte[],数组创建后大小不可变不可变性字符串重现赋值时,需要重新指定
2021-03-18 16:26:42
218
1
原创 对象实例化、内存布局、访问定位
文章目录对象实例化对象的内存布局对象访问定位对象实例化加载类元信息 虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化。(即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader+包名+类名为Key进行查找对应的.class文件。如果没有找到文件,则抛出ClassNotFoundException异常,如果找到,则进行类加载,并生成对应的C
2021-03-15 16:08:54
174
原创 运行时数据区(方法区)
文章目录栈、堆、方法区的交互关系方法区概述HotSpot中方法区的演进设置方法区大小与OOM方法区的内部结构类型信息域(Field)信息方法信息non-final的类变量栈、堆、方法区的交互关系方法区概述方法区看作一块独立于Java堆的内存空间,是各个线程共享的内存区域方法区在Java虚拟机启动时被创建,其实际的物理内存空间和Java堆一样,可以是不连续的,方法区的大小可以是固定大小或者是可扩展空间,关闭JVM会释放这个区域的内存方法区的大小决定了系统可以保存多少个类,如果系统定义了太多类,
2021-03-12 21:01:56
317
原创 二叉树层序遍历题目
目录102. 二叉树的层序遍历111. 二叉树的最小深度102. 二叉树的层序遍历领扣地址:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/class Solution { public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> res = new Ar
2021-03-10 22:32:55
115
原创 运行时数据区(堆)
概述一个JVM实例只存在一个堆内存Java堆在JVM启动时即被创建,其空间大小也确定了堆可以处在物理上不连续的空间中,但是在逻辑上应该被视为连续的在方法结束后,堆中的对象不会被马上移除,仅仅在垃圾收集的时候才会被移除-Xms用于表示堆区的起始内存,等价于-XX:InitialHeapSize-Xmx用于表示堆区的最大内存,等价于-XX:MaxHeapSize通常会将-Xms和-Xmx两个参数配置相同的值,其目的是为了避免频繁的扩容与垃圾回收,从而提高性能堆空间参数设置:https://do
2021-03-09 18:39:51
201
原创 运行时数据区(PC寄存器、虚拟机栈、本地方法栈)
运行时数据区在运行时数据区中,红色部分是由所有线程共享的数据区灰色部分是线程隔离的数据区程序计数器PC寄存器是一块较小的内存区域,可以看作当前线程所执行的字节码指令的行号指示器作用:PC寄存器用来存储指向下一条指令的地址,由执行引擎读取下一条指令每个线程都有自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致任何时间一个线程都只有一个方法在执行,就是当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;如果是在执行native方法,则是未
2021-03-06 21:58:40
174
原创 虚拟机类加载机制
类加载的时机类的生命周期有七个阶段其中,加载、验证、准备、初始化和卸载这五个阶段顺序是确定的,而解析阶段在某些情况下可以在初始化阶段之后进行主动引用:在初始化阶段,《Java虚拟机规范》严格规定了六种情况必须立即对类进行初始化遇到new、getstatic、putstatic、invokestatic四条字节码指令,类若果未进行过初始化,需要先进行初始化。能够生成这四条指令的典型场景: 使用new关键字实例化对象 读取或设置一个类型的静态字段时(被final修饰、已在编译器把结
2021-03-01 23:00:37
100
原创 Callable和Future用法解析
Callable和Future的关系可以用Future.get来获取Callable接口返回的执行结果,还可以通过Future.isDone()来判断任务是否已经执行完了在call()未执行完毕之前,调用get()的线程(假定此时是主线程)会被阻塞,直到call方法返回了结果后,此时future.get才会得到结果,然后主线程才会切换到runnable状态Future是一个存储器,存储了call()这个任务的结果,而这个任务的执行时间是无法提前确定的Future主要方法get():获取结果。
2021-01-28 18:07:08
4297
原创 控制并发流程的方式
CountDownLatch即倒数栅栏,有两种典型用法:一等多、多等一await():调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行countDown():将count()值减1,直到为0时,等待的线程会被唤醒CountDownLatch(int count):构造函数,参数count为需要倒数的数值一等多:一个线程等待多个线程都执行完毕,再继续自己的工作模拟工厂中,质检流程,5个质检工人检查,所有人都认为通过,才算通过 public cla
2021-01-27 22:55:06
193
2
原创 final关键字与不变性
不变性如果对象在被创建后,状态不能被修改,那么它就是不可变具有不变性的对象一定是线程安全的对象不可变的判断条件对象创建后,其状态不能改变所有属性都是final修饰的对象创建过程中没有发生逸出final的三种用法final修饰变量含义:被final修饰的变量,意味着值不能被修改。如果变量是对象,那么对象的引用不能变,但是对象自身的内容依然可以改变public class Person { final int age = 18; final String name
2021-01-26 17:55:21
147
4
原创 什么是CAS?
什么是CAS?CAS即Compare And Swap,就是把一个期望值与变量的当前值进行比较,如果当前变量的值与期望值相等,就使用这个新值来代替当前变量的值。下面是模拟CAS的代码:public class SimulatedCAS { private volatile int value; public synchronized int compareAndSwap(int expectedValue, int newValue){ int oldVal
2021-01-26 15:34:00
655
原创 Java中的锁--分类辨析
Lock接口为什么有synchronized了还要用Lock?效率低:锁的释放情况少、试图获得锁时不能设定超时、不能中断一个正在试图获得锁的线程不够灵活(读写锁更灵活):加锁和释放的时机单一、每个锁仅有单一的条件(某个对象)无法知道是否成功获取到锁主要方法:lock()lock()就是最普通的获取锁。如果锁被其他线程获取,则进行等待Lock不会像synchronized一样在异常时自动释放锁最佳实践应该是在finally中释放锁,以保证发生异常时锁一定被释放lock(.
2021-01-26 01:21:19
97
原创 Linux基础知识--用户管理
切换root用户在普通用户下,输入su,即切换到root用户添加用户useradd 用户名在普通用户下,创建用户的权限不足,要先转换成root用户在创建用户时,如果没有指定用户组,会自动创建与用户同名的用户组当创建用户成功后,会自动创建和用户同名的目录修改密码passwd 用户名删除用户删除用户,但保留用户主目录userdel 用户名删除用户,不保留主目录userdel -r 用户名 查询用户信息id 用户名查看当前用户whoami查
2021-01-22 00:23:34
81
原创 Linux基础知识--vim基本操作
菜鸟教程vim教程地址三种模式一般模式:即打开一个文件就进入了一般模式编辑模式:按i进入命令行模式:先按Esc退出编辑模式,再输入:进入该模式常用快捷键输入、保存、退出输入i进入编辑模式,编辑完成后,Esc退出编辑模式,输入:wq,表示保存后退出:q!表示不保存强制退出复制粘贴在一般模式下复制当前行:yy复制当前行向下4行:4yy粘贴:p删除一般模式下删除当前行:dd删除当前行向下5行:5dd查找关键字在命令行模式下查找:/关键.
2021-01-21 23:10:28
144
原创 ThreadLocal用法、原理
一、ThreadLocal两大使用场景场景一每个线程需要一个独享的对象,即该对象在线程间隔离(通常是工具类,典型需要使用的类有SimpleDateFormat和Random)下面程序中用ThreadSafeFormatter初始化了SimpleDateFormat实例,在每个线程调用时,都是一个独立的对象,做到了线程间的隔离public class ThreadLocalNormalUsage05 { public static ExecutorService threadPool =
2021-01-20 16:08:21
220
2
原创 JMM内存模型--重排序、可见性、原子性
为什么需要JMM(Java Memory Model)?C语言不存在内存模型的概念,很多行为依赖于处理器,不同处理器的操作会导致运行结果不一样,所以不能保证并发安全JMM是一组规范,也是工具类和关键字的原理JMM最重要的三点内容:重排序、可见性、原子性一、重排序1、重排序例子下面是一个演示重排序的例子,一个线程执行a = 1; x = b,一个线程执行b = 1; x = bpublic class OutOfOrderExecution { private static .
2021-01-18 15:33:27
184
原创 多线程核心8-3:线程三大安全问题之发布与逸出
发布与逸出的概念发布:对象能够在作用域范围外被使用,则这个对象被发布出去了逸出:被发布到了不该发布的地方,以下是逸出的两种情况:方法返回一个private对象未完成初始化(构造函数还未执行完毕)就将对象提供给外界在构造函数中未完成初始化完毕就用this赋值隐式逸出–注册监听事件构造函数中运行线程例子与解决方法方法返回private对象的情况在例子中return了一个private修饰的对象,即将该私有对象发布出去了 public class MultiThreadEr
2021-01-14 00:01:19
229
2
原创 多线程核心8-2:线程三大安全问题之死锁
一个必然死锁的例子public class MultiThreadError2 implements Runnable { int flag = 0; static Object o1 = new Object(); static Object o2 = new Object(); public static void main(String[] args) { MultiThreadError2 r1 = new MultiThreadError2();
2021-01-13 21:42:28
87
原创 多线程核心8-1:线程三大安全问题之运行结果错误
两个线程导致的错误两个线程进行index++操作,两个线程会相互干扰,导致结果不一定准确,现在想找出出错的位置和出错次数public class MultiThreadError1 implements Runnable { static MultiThreadError1 instance = new MultiThreadError1(); int index = 0; public static void main(String[] args) throws Inte
2021-01-13 21:38:48
140
原创 多线程核心7:处理未捕获的异常
使用UncaughtExceptionHandler的原因主线程可以轻松发现异常,子线程不能子线程的异常无法用传统方式捕获在捕获到异常时也能进行处理,提高健壮性全局异常处理使用方式实现Thread.UncaughtExceptionHandler接口public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private String name; public
2021-01-06 20:33:41
124
原创 多线程核心6:线程的属性
线程Id线程的Id不是从0开始,而是从1开始,原因是先做了++操作线程id会自动递增,在创建线程时,不单是创建了一个主线程和一个子线程,jvm 也创建了一系列线程,因此子线程 Id 并不是2public class ID { public static void main(String[] args) { Thread thread = new Thread(); System.out.println(Thread.currentThread().getId.
2021-01-06 19:43:58
123
原创 多线程核心5:Thread和Object类中线程相关方法
一、wait()、notify()、notifyAll()wait():导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或指定的时间已过。 即释放所拥有的monitor,直到重新获得注意:wait()要在同步代码块中使用,是为了防止拥有notify()的线程先执行了,导致死锁notify()和notifyAll():分别是唤醒单个线程和所有线程public class Wait { public static Object object
2021-01-06 18:58:38
118
原创 多线程核心4:线程的六种状态
状态转换图一般把Blocked(被阻塞)、Waiting(等待)、Timed_waiting(计时等待)都称为阻塞状态六种状态具体代码线程刚创建好,还未启动,这时属于NEW状态,线程处于就绪状态或者正在运行,都是属于RUNNABLE,运行结束,进入TERMINATEDpublic class NewRunnableTerminated implements Runnable { @Override public void run() { for (int i
2021-01-04 16:58:19
144
原创 多线程核心3:线程的正确停止方式
正确方式如何正确的停止线程?原理:使用interrupt来通知,而不是强制原因是通常情况下会认为发出停止请求的线程并不清楚被停止的线程的状态和细节,所以要把停止的决定权交给线程本身,而不是其它线程通常线程会在什么情况下停止?run方法中所有的代码运行完毕run方法中有异常出现,但未被捕获处理使用正确方法停止线程会有以下几种情况:run方法内没有sleep或wait方法,停止线程main线程和Thread-0线程要相互配合才能起到作用/** * 在子线程Thread-
2021-01-02 20:52:57
158
原创 多线程核心2:多线程启动方式
start()与run()启动public class StartAndRunMethod { public static void main(String[] args) { Runnable runnable = () -> { System.out.println(Thread.currentThread().getName()); }; runnable.run(); new Thread(r
2021-01-01 14:22:43
129
原创 多线程核心1:实现多线程的方式
实现多线程的方法实现Runnable接口public class RunnableStyle implements Runnable { public static void main(String[] args) { Thread thread = new Thread(new RunnableStyle()); thread.start(); } @Override public void run() { Sys
2021-01-01 01:44:00
162
4
原创 Synchronized基本用法、性质和原理
Synchronized的两种用法Synchronized作用:能够保证在同一时刻最多只有一个线程执行该代码,以达到保证并发安全的效果对象锁方法锁:Synchronized修饰普通方法,默认锁对象为this当前实例对象同步代码块锁:手动指定锁对象类锁Synchronized修饰静态的方法指定锁为Class对象,类锁只能在同一时刻被一个对象拥有多线程访问同步方法的7种情况两个线程同时访问一个对象的同步方法争抢同一把锁,相互等待public class Sy
2020-12-31 21:59:37
108
原创 第三章 处理机调度与死锁
一、处理机调度的层次和调度算法的目标处理机调度的层次高级调度:又称长程调度或者作业调度,调度对象是作业中级调度:又称内存调度,目的是提高内存利用率和系统吞吐量二、作业与作业调度三、进程调度四、实时调度五、死锁概述六、预防死锁七、避免死锁八、死锁的检测与解除...
2020-11-29 15:07:13
532
原创 JVM系列笔记--字节码与类加载
一、字节码指令反编译可使用javap -v className.class来反编译class文件public class Demo3_1 { public static void main(String[] args) { int a = 10; int b = Short.MAX_VALUE + 1; int c = a + b; System.out.println(c); }}Classfile /D:/dow
2020-11-10 16:24:03
189
原创 JVM系列笔记--垃圾回收
对象回收引用计数法在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的public class ReferenceCoutingGC { public Object instance = null; private static final int _1MB = 1024*1024; private byte[] bigSize = new byte[2 * _1MB]; p
2020-11-05 17:07:05
161
原创 JVM系列笔记--内存结构
运行时的数据区域程序计数器程序计数器(Program Counter Register)是一块较小的内存空间,是当前线程所执行的字节码的行号指示器,作用是用来选取下一条需要执行的字节码指令各条线程之间计数器互不影响,独立存储,线程私有的内存区域如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空此区域不会有内存溢出(OutOfMemoryError)虚拟机栈每一个方法被调用直至执行完毕的
2020-11-03 23:36:05
91
原创 进程同步问题总结
生产者-消费者问题类由三个进程get,copy和put以及两个缓冲区buffer1和buffer2完成一项输入/输出操作。进程get的功能是把一张卡片上的信息从读卡机上读进buffer1;进程copy的功能是把buffer1中的信息复制到buffer2;进程put的功能是取出buffer2中的信息并从打印机上打印输出。试用P、V操作完成这三个进程间的尽可能并发正确执行的关系(用程序或框图表示),并指明信号量的作用和初值。分析:可设置6个信号量mutex1,mutex2,empty1,empty2,fu
2020-10-30 23:12:53
2573
1
原创 第二章 进程的描述与控制
一、程序执行顺序执行的特征顺序性封闭性:程序运行时独占全机资源可再现性并发执行间断性失去封闭性不可再现性二、进程的描述进程的定义由程序段、相关的数据段和PCB三部分构成进程实体(又称进程映像)创建进程,实际上是创建进程实体中的PCB;而撤销进程,实质上是撤销进程的PCB典型定义:进程是程序的一次执行进程是一个程序及其数据在处理机上顺序执行时所发生的活动进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位进程是进程实体的
2020-10-30 21:17:58
82
原创 Spring Boot系列笔记--整合Redis
基本环境搭建导入依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency>配置文件配置Redis主机地址,端口默认6379spring.redis.host=127.0.0.1RedisTemplate.
2020-10-29 17:31:41
152
1
原创 Spring Boot系列笔记--缓存
Spring缓存抽象CacheManager管理多个Cache组件的,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字使用缓存即要使用相同的数据时,直接从缓存中获取,而不用调用方法查询数据库缓存注解@Cacheable@Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据几个属性:cacheNames/value:指定缓存组件的名字
2020-10-28 22:12:42
204
1
原创 Spring Data Jpa总结--查询方式、多表关系
Spring Data Jpa基本说明操作步骤创建实体类,建立与数据表的关联编写一个符合Jpa规范的Dao层接口完成CRUD操作接口说明JpaRepository<实体类类型, 主键类型>:接口中封装了一些基本的增删查改方法JpaSpecificationExecutor<实体类类型>:完成一些复杂操作,如分页查询,可完成动态查询,即自定义查询条件@Testpublic void testSpec(){//查询 //自定义查询条件 S
2020-10-26 16:04:33
144
原创 第一章 操作系统引论 总结
操作系统的目标和作用目标方便性有效性:(1)提高系统资源的利用率 (2)提高系统的吞吐率可扩展性开放性作用用户与计算机硬件系统之间的接口计算机系统资源的管理者资源有四类:处理机、存储器、I/O设备、文件(数据和程序)处理机管理用于分配和控制处理机存储器管理负责内存的分配与回收I/O设备管理负责I/O设备的分配(回收)与操纵文件管理用于实现对文件的存取、共享、保护实现了对计算机资源的抽象操作系统的发展过程单道批处理系统缺点:系统中的资源得不到充分的利用
2020-10-21 16:18:19
214
原创 IDEA中使用Git(图示)
基本配置找到Git安装位置,添加git.exe项目所在目录出现.git即为初始化成功编写.gitignore文件将文件添加到暂存区提交到本地仓库推送到远程服务器从远程仓库拉取项目到IDEA中对比历史版本新建分支...
2020-10-19 23:37:20
335
原创 Git常用命令--本地仓库、远程仓库、分支
环境配置设置/重设用户信息git config --global user.name “xxx”git config --global user.email “xxxx@xxxxxx”查看配置信息git config --listgit config --user.name以上命令设置的信息通常会默认保存在C:\Users\xxx\.gitconfig文件中[user] email = xxxx@xxxxxx name = xxx[gui] encoding = ut
2020-10-19 18:01:00
617
原创 Spring Boot系列笔记--数据访问
一、JDBCSpringBoot使用JDBC只需导入相应依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency> <groupId>mysql</groupId>
2020-10-16 22:55:54
109
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人