![](https://img-blog.csdnimg.cn/20210327225238512.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
javase
JavaSE 学习笔记
ljt-tiger
不积跬步,无以至千里。知识认知体系搭建过程:场景 --》需求 --》解决方案 --》应用 --》原理
展开
-
java注解学习
从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。原创 2023-01-07 21:06:18 · 294 阅读 · 0 评论 -
PDF导出-复杂样式【像搭积木一样排版】
本文通过lowagie.text在java程序中画出复杂PDF样式并生成文件导出原创 2022-06-01 14:49:16 · 441 阅读 · 0 评论 -
java对象的内存布局
Hotspot虚拟机对象头(Header)对象标记mark-word:对象标记字段占4个字节,用于存储一些列的标记位,比如:哈希值、轻量级锁的标 记位,偏向锁标记位、分代年龄等。 Klass Pointer:Class对象的类型指针,Jdk1.8默认开启指针压缩后为4字节,关闭指针压缩( - XX:-UseCompressedOops )后,长度为8字节。其指向的位置是对象对应的Class对象(其对应的 元数据对象)的内存地址。hashcode分代年龄同步锁标记偏向锁标记偏向锁持有线程ID原创 2022-03-20 20:31:44 · 719 阅读 · 0 评论 -
ConcurrentHashMap
ConcurrentHashMap特点并发安全集合,存在多线程访问的情况下使用的集合工具;另外这种也行【Collections.synchronizedMap();】,将非现场安全转为线程安全。CHM 中是支持并发扩容的,也就是说如果当前的数组需要进行扩容操作,可以由多个线程来共同负责。扩容是 ConcurrentHashMap 的精华之一,扩容操作的核心在于数据的转移,在单线程环境下数据的转移很简单,无非就是把旧数组中的数据迁移到新的数组。但是这在多线程环境下,在扩容的时候其他线程也可能正在添加原创 2022-03-13 23:47:39 · 269 阅读 · 0 评论 -
CountDownLatch
CountDownLatch使用场景涉及到需要指定某个事物在执行之前,要等到前置人物执行完毕之后才执行特点允许一个或多个线程一直等待,直到其他线程的操作执行完毕再执行。从命名可以解读到 countdown 是倒数的意思,类似于我们倒计时的概念。countdownlatch 提供了两个方法,一个是 countDown,一个是 await,countdownlatch 初始化的时候需要传入一个整数,在这个整数倒数到 0 之前,调用了 await 方法的程序都必须要等待,然后通过 countDown原创 2022-03-13 22:36:51 · 497 阅读 · 0 评论 -
软引用 SoftReference
import java.lang.ref.SoftReference;/**软引用demo,和使用redis缓存类似,先查内存中是否缓存,有则直接内存获取,反之则重新创建,再装载入内存中缓存起来。在一些开源框架中经常使用@author: tiger@create: 2021-09-12 20:34*/public class SoftReferenceDemo {public static void main(String[] args) { Tiger ti原创 2021-09-12 20:49:26 · 245 阅读 · 0 评论 -
线程池-ThreadPoolExecutor
线程池-ThreadPoolExecutor使用场景想要频繁的创建和销毁线程的时候线程池的概念线程池就是提前创建若干个线程,如果有任务需要处理,线程池里的线程就会处理任务,处理完之后线程并不会被销毁,而是等待下一个任务。由于创建和销毁线程都是消耗系统资源的线程池的优势降低创建线程和销毁线程的性能开销提高响应速度,当有新任务需要执行是不需要等待线程创建就可以立马执行合理的设置线程池大小(限流)可以避免因为线程数超过硬件资源瓶颈带来的问题Api ExecutorsnewFixedTh原创 2021-07-03 20:49:22 · 123 阅读 · 0 评论 -
BlockingQueue
BlockingQueue堵塞队列,有两种情况会堵塞队列满时,入队线程会被堵塞队列空时,出对线程会被堵塞操作Throws ExceptionSpecial ValueBlocksTimes Out添加add(o)offer(o)put(o)offer(0,timeout,timeunit)移除remove(o)poll()take()poll(timeout,timeunit)检查element()peek()...原创 2021-07-03 10:01:55 · 190 阅读 · 0 评论 -
Fork/Join
Fork/Join用于并行执行任务,将大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。使用工作窃取算法,某个线程从其他队列里窃取任务来执行fork:将大任务切割成若干个子任务并行执行join:合并子任务的执行结果得到大任务的结果…局限性不能执行I/O操作(读写数据文件)不能抛出检查异常,必须通过必要的代码来处理他们任务只能使用fork和join操作来作为同步机制,如果使用其他同步机制,那么执行任务时,工作线程就不能执行其他任务import lombok.e原创 2021-07-03 09:36:01 · 113 阅读 · 0 评论 -
FutureTask
FutureTask多线程执行任务时,有比较耗时操作,但又需要其返回结果时,可以使用FutureTaskpublic class FutureTaskDemo { public static void main(String[] args) throws Exception { FutureTask<String> futureTask = new FutureTask<String>(() -> { log.info("d原创 2021-07-03 09:35:01 · 127 阅读 · 0 评论 -
Condition
Condition多线程协调调度的工具public class LockExample6 { public static void main(String[] args) { ReentrantLock reentrantLock = new ReentrantLock(); Condition condition = reentrantLock.newCondition(); new Thread(() -> {原创 2021-06-27 10:57:33 · 94 阅读 · 0 评论 -
Lock 锁
ReentrantLock大部分情况下可以使用 synchronized,性能上并无太大差别,使用ReentrantLock要特别注意在finally中释放锁,不然容易出现死锁。特性可指定公平和非公平锁提供Condition类,可分组唤醒需要唤醒的线程提供能够中断等待锁的线程自旋,避免锁进入内核态…public class LockExample2 { // 请求总数 public static int clientTotal = 5000; // 同时并发执行的原创 2021-06-26 13:37:20 · 120 阅读 · 0 评论 -
CyclicBarrier,线程屏障
CyclicBarrier使用场景:【当存在需要一组子任务都完成时,才执行主任务】CyclicBarrier:让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续工作。CyclicBarrier 默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用 await 方法告诉 CyclicBarrier 当前线程已经到达了屏障,然后当前线程被阻塞。…import lombo原创 2021-06-26 10:23:05 · 178 阅读 · 0 评论 -
Semaphore,信号量,限流操作
Semaphore使用场景:【限流操作】,限制某个资源同时被访问的个数semaphore 也就是我们常说的信号灯,semaphore 可以控制同时访问的线程个数,通过 acquire 获取一个许可,如果没有就等待,通过 release 释放一个许可。…import lombok.extern.slf4j.Slf4j;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import原创 2021-06-26 10:00:21 · 299 阅读 · 0 评论 -
线程封闭的几种方式
线程封闭的几种方式Ad-hoc 线程封闭程序控制实现,很糟糕,可以忽略堆栈封闭局部变量,无并发问题ThreadLocal很好的封闭方法原创 2021-06-15 23:48:39 · 156 阅读 · 0 评论 -
几种不可变类的写法
几种不可变类的写法引入 guava <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency>finalpublic class原创 2021-06-15 22:21:11 · 99 阅读 · 0 评论 -
几种单例模式
几种单例模式枚举可以天然防止反射和反序列化漏洞 需要延时加载时:枚举好于饿汉式 ,不需要延时加载:静态内部类好于懒汉式 也就是说优先选用 枚举和静态内部类饿汉/** * 饿汉式单例设计模式 * 特点:线程安全、调用效率高、资源利用率低(无懒加载)。 * * @author tiger * @Date 2017年9月2日 */public class SingletonHungry { // 私有构造函数 private SingletonHungry() { }原创 2021-06-14 23:47:24 · 82 阅读 · 1 评论 -
volatile使用场景-标志位
volatile使用场景标志位volatile boolean inited = false;// 线程1String context = loadContext();// 线程2while(!inited){ sleep();}doSomethingWithConfig(context);原创 2021-06-14 17:08:25 · 169 阅读 · 0 评论 -
CAS使用理解
当前内存值(V)、预期原来的值(E)、期待更新的值(N)原创 2021-06-14 17:02:20 · 340 阅读 · 0 评论 -
linux反向查找jdk的安装路径
逐步查找[root@VM-0-8-centos jvm]# which java/usr/bin/java[root@VM-0-8-centos jvm]# clear[root@VM-0-8-centos jvm]# which java/usr/bin/java[root@VM-0-8-centos jvm]# ls -lrt /usr/bin/javalrwxrwxrwx 1 root root 22 Mar 27 14:58 /usr/bin/java -> /etc/alt..原创 2021-06-06 15:17:19 · 114 阅读 · 2 评论 -
linux安装jdk
linux中安装jdk的几种常用方式原创 2019-03-09 12:43:49 · 137 阅读 · 0 评论 -
JMM (JAVA内存模型)
JMM (JAVA内存模型)内存屏障、重排序这些东西好像是和平台以及硬件架构有关系的。作为 Java 语言的特性,一次编写多处运行。我们不应该考虑平台相关的问题,并且这些所谓的内存屏障也不应该让程序员来关心JMM 全称是 Java Memory Model. 什么是 JMM 呢?通过前面的分析发现,导致可见性问题的根本原因是缓存以及重排序。 而 JMM 实际上就是提供了合理的禁用缓存以及禁止重排序的方法。所以它最核心的价值在于解决可见性和有序性JMM 属于语言级别的抽象内存模型,可以简单理解为对硬件原创 2021-05-30 18:13:17 · 126 阅读 · 1 评论 -
查看运行代码的汇编指令的工具
将hsdis-amd64.dll和hsdis-amd64.lib文件,复制到JRE_HOME/bin/server路径下在运行main函数之前,加入虚拟机参数// *CLassLayoutDemo.getInstance 替换成实际运行的代码-server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*CLassLayoutDemo.getInstance...原创 2021-05-30 16:28:02 · 154 阅读 · 0 评论 -
synchronized(锁的升级过程)
synchronized可以解决【原子性、有序性、可见性问题、[对象逃逸]】,也就是解决了线程安全问题线程安全概念:在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。本质是管理对数据状态的访问数据是共享的,在线程生命周期里是变化的锁的状态假如有两个线程 ThreadA 和 ThreadB只有线程 ThreadA 去访问(如果这种情况属于大部分情况时)–》偏向锁ThreadA 和 ThreadB原创 2021-05-30 16:02:21 · 122 阅读 · 0 评论 -
java基本数据类型大小和单位换算
单位换算1Byte=8bit1KB=1024Byte(字节)=8*1024bit1MB=1024KB1GB=1024MB1TB=1024GB1PB=1024TB类型32位64位boolean1 byte1 bytebyte1 byte1 bytechar2 byte2 byteshort2 byte2 byteint4 byte4 bytefloat4 byte4 bytelong8 byte8 byte原创 2021-05-30 11:37:08 · 583 阅读 · 0 评论 -
对齐填充的目的
概念cup一次读取的数据是缓存行,按块(x86架构64位计算机中是64字节)进行读取,也就是说缓存行是CUP与内存交互的最小工作单元没有对齐填充时,A线程只想要读取一个long类型的变量a,但a只占8字节,因此会连带变量b、c、d也会一并读取到缓存行中;而同一时刻B线程只想要读取一个long类型的变量b,但b只占8字节,因此会连带变量a、c、d也会一并读取到缓存行中;那么这种情况下就会存在伪共享问题,这会导致A和B线程在进行数据操作时会频繁地直接去内存获取最新值,而不是从高速缓存中获取(也就是缓存失效)原创 2021-05-30 11:16:51 · 956 阅读 · 3 评论 -
查看对象在内存中布局
引入jar包 <dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.9</version> </dependency>使用案例package com.tiger;import org.openjdk.jol.info.Cl原创 2021-05-29 22:03:27 · 123 阅读 · 0 评论 -
静态导入
import static io.netty.handler.codec.http.HttpHeaders.Names.*;import static io.netty.handler.codec.http.HttpHeaders.isKeepAlive;import static io.netty.handler.codec.http.HttpHeaders.setContentLength;import static io.netty.handler.codec.http.HttpMethod..原创 2021-05-04 21:54:29 · 98 阅读 · 0 评论 -
volatile关键字的深入理解
volatile关键字的深入理解问题引起的缘由:硬件层面的优化带来的共享数据a可见性问题由于CUP/内存/IO/磁盘三者之间的处理速度的差异引发的优化,CPU进行数据运算时需要存取内存中的数据,但他们之间的速度差异很悬殊;1、第一步优化是引入了高速缓存,分别L1/L2/L3缓存(速度逐级递减),而每个CPU都有自己的缓存(相当于L1),而多个CPU在访问共享资源时,会出现数据安全性问题,及CPU1改了某个共享资源a的值时,没有及时同步到主内存,而CUP2在计算a的值时不是拿的最新数据。2、因此,这.原创 2020-10-30 00:03:32 · 90 阅读 · 0 评论 -
基于tcp自己实现简单的HTTP服务器
1、解析:在浏览器中输入url向服务器提交一个请求,服务器接受到一窜字符串,之后便可以从中提取出一个重要的信息 uri 【/tiger.html】GET /tiger.html HTTP/1.1,服务器便可以根据客户端提交的uri对其进行反馈,利用字节输出流将uri资源拼凑为http协议的格式输出到浏览器显示。2、代码演示如下:package com.linjitai.http;i原创 2017-08-28 20:04:13 · 3636 阅读 · 1 评论 -
网络编程中(socket)用户登录验证以及注册(单用户)
网络编程中(socket)用户登录验证以及注册(单用户)原创 2017-08-01 19:20:25 · 7375 阅读 · 0 评论 -
踩坑记录--list.remove()方法陷阱
一、首先说正确的方式1、让索引同步调整 for (int i = 0; i < list.size(); i++) { Apple apple = list.get(i); if(apple.getWeight()==23){ list.remove(i--); } }2、倒序遍历List删除元素 for (int i = list.s原创 2020-07-07 22:23:43 · 392 阅读 · 2 评论 -
向集合中一次性添加一组元素的方法
向集合中一次性添加一组元素的方法原创 2017-08-20 13:55:55 · 4065 阅读 · 0 评论 -
基于Object/数组模拟实现ArrayList的增、删、改、查
1、定义了一个DataList接口,里面包含了所需要实现的方法2、用MyArrayList实现DataList接口,实现里面所定义的方法3、扩容的核心思想:可以实现动态扩容,当检测到数组容量不够时,自动扩大为原来的1.5倍,扩容的核心思想是将旧数组copy到新数组,再将新数组赋值给当前数组。原创 2017-07-12 08:50:46 · 497 阅读 · 0 评论 -
使用反射以及泛型技术相结合实现简单工厂模式
接口可以随意更改替换成别的接口,也可以在其他包引入,(测试例子中的接口是Human),但只满足接口中定义的方法没有参数的情况下。转载 2017-09-04 19:19:25 · 646 阅读 · 0 评论 -
自定义运行器以及编译器
自定义运行器以及编译器1、编译:javac MyRunner.java2、动态编译运行:java MyRunner Person prt原创 2017-08-06 14:53:48 · 566 阅读 · 0 评论 -
使用反射技术操作方法所有细节
1、使用反射技术操作方法所有细节2、代码演示如下:package com.reflect.api.method;import java.lang.reflect.*;import com.reflect.bean.Cat;/** * 使用反射技术操作方法所有细节 * @author tiger * @Date 2017年8月3日 */publ原创 2017-08-03 20:22:56 · 483 阅读 · 1 评论 -
模拟银行转账信息
从本地 data.txt 文本中读取账户信息,模拟银行不同账户之间的转账信息原创 2017-07-26 23:10:13 · 2945 阅读 · 0 评论 -
文件过滤器
1、自定义一个过滤器MyFilter,在里边实现自己的过滤逻辑。2、之后就可以传入自己的过滤器,实现过滤功能。原创 2017-07-25 09:13:24 · 1105 阅读 · 0 评论 -
复制文件的三种方法
复制文件的三种方法:1、Files.copy(path, new FileOutputStream(dest));。2、利用字节流。3、利用字符流。原创 2017-07-24 09:06:07 · 4798 阅读 · 0 评论