°Fuhb
要比别人得到更多,就要付出比别人更多的努力
展开
-
Java线程知识整理汇总
优先级 priority所有线程都有优先级属性 priority,值比较大的会被优先执行priority 最小值是 1,最大值是 10,默认值是 5子线程 priority 的初始值跟父线程的 priority 一致守护线程 daemonJava 线程有2种类型:用户线程和守护线程。用户线程是必需的,而守护线程不一定。当所有用户线程都结束了,程序也就终止了,守护线程会随之被终止。反过来说,如果守护线程都结束了,程序并不一定会结束。设置属性 daemon = true,表示当前线程是守护线原创 2021-10-24 08:00:00 · 245 阅读 · 0 评论 -
Java线程6个状态详解
文章目录1. 概述2. 举例说明2.1 NEW2.2 RUNNABLE2.3 BLOCKED2.4 WAITING2.5 TIMED_WAITING2.6 TERMINATED1. 概述Java线程状态由 Thread#State 枚举定义,有以下6种:public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;}NEW:初始状态,线程创建后还没开始运行RUNNABLE:运行状态,包原创 2021-10-18 22:00:01 · 333 阅读 · 0 评论 -
Java DelayQueue延迟队列的使用和源码分析
概述原创 2021-09-20 22:09:53 · 194 阅读 · 0 评论 -
Java PriorityQueue优先队列详解(源码+图文步骤解析)
概述PriorityQueue 称为优先队列,也是一种特殊的有序队列。为什么特殊呢?因为其内部使用 Object[] 数组来存储数据,整个数组从0 ~ 最后一个并不是有序排放的,但是出队的时候数据又是从小到大有序的。...原创 2021-09-15 21:59:16 · 386 阅读 · 0 评论 -
Java 常见的OOM类型总结
文章目录StackOverflowErrorJava heap spaceGC overhead limit exceededMetaspaceStackOverflowError说明:栈空间溢出举例:递归无限调用,不设置结束点,会导致栈空间爆满 public static void stackOverflowError(){ stackOverflowError(); }Java heap space说明:堆空间溢出举例:设置最大堆空间10m,然后创建一个2原创 2021-06-18 08:56:00 · 590 阅读 · 6 评论 -
MAT分析器查看jvm dump文件
创建dump文件方式一:使用 jmap 命令创建,例如 jmap -dump:format=b,file=heapdump.hprof 27012(进程ID)方式二:运行java程序的时候开启HeapDumpOnOutOfMemoryError参数(发生OOM的时候自动创建dump),例如 java -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError HelloWorld分析dump文件MAT工具下载地址:https://www.eclipse.org原创 2021-05-13 20:53:37 · 1803 阅读 · 1 评论 -
Java jmap查看堆内存
https://zhanghan.blog.csdn.net/article/details/109255980原创 2021-05-13 16:58:42 · 1324 阅读 · 0 评论 -
Java强引用、软引用、弱引用、虚引用的区别
文章目录强引用软引用弱引用虚引用总结强引用只要对象的引用仍然存在,就永远不会被GC回收,即便JVM内存不够用了也不回收。 public static void strongReference(){ Object a = new Object(); System.out.println("回收前:" + a); System.gc(); System.out.println("回收后:" + a); }输出结果如下:原创 2021-05-13 10:33:04 · 337 阅读 · 1 评论 -
Java使用BTrace动态替换线上class文件
概述BTrace的功能主要是动态替换线上正在运行的class文件,一般用来增加打印所需要的日志。安装BTrace下载地址:https://github.com/btraceio/btrace/releases/tag/v1.3.11原创 2021-05-12 16:26:51 · 435 阅读 · 1 评论 -
JVM 年轻代(Eden、From、To)、老年代讲解
概述JVM 的堆空间分成2个区域:年轻代、老年代年轻代又进一步细分成3个区域:Eden、Survivor From、Survivor To如下图所示:默认情况下,年轻代与老年代比例为1:2。可以通过参数-XX:NewRatio修改,NewRatio默认值是2。如果NewRatio修改成3,那么年轻代与老年代比例就是1:3默认情况下Eden、From、To的比例是8:1:1。可以通过参数-XX:SurvivorRatio修改,SurvivorRatio默认值是8,如果SurvivorRatio修原创 2021-05-10 21:30:29 · 9477 阅读 · 2 评论 -
JVM PrintGCDetails打印GC细节
准备工作设置IDEA启动参数:-Xms10m -Xmx10m -XX:+PrintGCDetails最小堆空间10m最大堆空间10m开启打印GC细节运行如下程序,创建一个20mb大小的对象public class App { public static void main( String[] args ) throws InterruptedException { byte[] bytes = new byte[20 * 1024 * 1024];原创 2021-05-10 15:10:00 · 994 阅读 · 0 评论 -
JVM命令查看与设置参数
Boolean类型公式-XX:+ 或者 - 某个属性值+表示开启-表示关闭测试是否打印GC收集细节是否使用KV设置类型原创 2021-05-08 22:59:19 · 239 阅读 · 0 评论 -
Java源码解析:ArrayList 和 Iterator 使用上的不同
文章目录1. 前言2. iterator 对象是什么类型?1. 前言ArrayList 是最常用的 List 类型,它提供了非常便捷的方法对数据进行增删改查,例如:add、remove、get、contains 等等。但是,实际应用中,我们经常需要在 for 循环判断数据,然后删除数据,ArrayList 在这方面的操作上是非常不方便的。下面我们看几个例子:案例一: 在循环 for (String s : list) 进行删除数据:public class MyList { public s原创 2021-02-26 09:05:54 · 279 阅读 · 0 评论 -
Java动态代理详解(Proxy+InvocationHandler)
1. 什么是代理以商品的生产、销售为例。现有某品牌U盘的生产工厂,该工厂并不直接销售U盘给我们,而是批发卖给N个商家,然后由商家进行销售。我们可以理解为,商家就是工厂的代理。商家作为代理,可以实现工厂所不具备的功能,例如:对会员用户进行打折优惠对黑名单用户禁止销售对部分用户赠送优惠券……2. 静态代理2.1 静态代理代码示例仍然以U盘为例,现有如下角色:U盘生产工厂:金士顿工厂、闪迪工厂销售商家:金士顿商家、闪迪商家客户(购买者)接口类 UsbSellService原创 2021-02-24 14:27:12 · 264 阅读 · 0 评论 -
Java静态代码块详解
简介众所周知,Java的构造函数是实例化对象的时候调用,每次new对象的时候都会调用一次构造函数。但是,如果我们需要在类加载的时候,自动调用并只执行一次初始化,就不能使用常规构造函数了。有些编程语言提供了静态构造函数pubilc static Person() 的写法,然而Java并不支持,我们可以使用静态代码块来实现同样的效果。静态代码块特点:随着类的加载而执行,并且只会执行一次例子:public class TestApp { public static void main(Stri原创 2021-02-06 12:20:02 · 425 阅读 · 0 评论 -
Java进阶:synchronized使用详解
https://blog.csdn.net/zjy15203167987/article/details/82531772原创 2021-02-06 10:26:23 · 129 阅读 · 0 评论 -
SpringBoot使用OpenOffice将word转成pdf
文章目录安装引用依赖创建操作类 OfficeToPdf注意事项安装参考这篇文章:Linux环境下安装OpenOffice 4.1.8引用依赖这边 jodconverter 用的是 2.2.2 版本,Maven库没有,需要自己去网上下载我这边是引用本地JAR,这是因为产生了大量WARN日志(找不到JAR包之类的)。虽然不影响使用,但是看着不舒服,所以把相关JAR放到同一个目录下引用了。 <!--jodconverter 开始 --> <depen原创 2021-01-27 11:44:29 · 892 阅读 · 0 评论 -
java处理IOS无法播放视频流(Accept-Ranges)
最近在做一个在线播放视频流的程序,安卓和电脑上都可以正常的播放。可以唯独ios上无法正常播放。开始在网上找了很多资料觉得不是很到位,所以在这里记录一下。刚开始时代码返回的视频流是在一个请求里全部返回的,而苹果的浏览器会先发一次探测请求来获取文件大小,之后再发送多次请求来分段取数据流的数据,其实这里就是一个分段上传的思想(Accept-Ranges)。有两个很重要的点就是,第一:需要根据请求内容的不同做出不同的响应,第一次探测请求需要返回200,后面的请求需要返回206和具体数据第二:conte转载 2020-12-28 17:05:14 · 1596 阅读 · 3 评论 -
javac和java命令的使用
javac作用:编译命令,将 java 文件编译成 class 字节码文件例如,现在有一个文件 HelloWorldApp.java:public class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello abc"); }}执行 javac 编译命令javac HelloWorldApp.java生成了一份 HelloWorldApp.cl原创 2020-12-27 18:44:38 · 318 阅读 · 0 评论 -
cglib库Enhancer、Callback的使用
概述cglib是Code Generation Library的简称,它是一个高效的代码生成库。类似的还有JDK动态代理,但是JDK动态代理要求源对象必须实现接口,而我们的项目中并非所有类都实现接口。此时,我们就可以使用cglib在无接口的类进行动态代理。注意:使用cglib代理的类不用有final修饰final修饰的方法无法切入先来看一段简单的代码: public static void main(String[] args) { Enhancer enhancer原创 2020-12-20 14:07:02 · 1509 阅读 · 1 评论 -
Java获取List泛型的真实类型
public static Class getActualType(Field field){ Class<?> fieldType = field.getType(); // 集合List元素 if (fieldType.equals(List.class)) { // 当前集合的泛型类型 Type genericType = field.getGenericType(); .原创 2020-12-05 15:11:38 · 6429 阅读 · 0 评论 -
Java多线程(五):线程池应该设置多少核心线程数
创建线程池有个CorePoolSize参数,指的是核心线程数,该参数应该设置为多大呢?CPU密集型一般公式:CPU核数 + 1通过以下代码动态获取CPU核数:Runtime.getRuntime().availableProcessors()IO密集型(1)配置方式一IO密集型任务线程并不是一直在执行任务,则应该配置尽可能多的线程例如:CPU核数 * 2(2)配置方式二CPU核数 / (1 - 阻塞系数),阻塞系数在0.8~0.9之间两种方式并没有绝对的最优,实际生产环境原创 2020-11-08 13:06:28 · 5915 阅读 · 0 评论 -
Java多线程(四):使用Executors创建线程池及其注意事项
文章目录1. 简介2. newCachedThreadPool3. newFiexedThreadPool4. newSingleThreadExecutor5. newScheduledThreadPool6. 注意事项(必看)1. 简介Executors 也是创建线程池的工具,通过Executors 可以简单地创建线程池对象。主要包括以下4种创建方式:newCachedThreadPool:创建一个可缓存的线程池。每个创建的线程默认偶60秒空闲时间,前面创建的线程只要还没被回收,并且处于空闲状原创 2020-11-07 16:27:16 · 507 阅读 · 0 评论 -
Java多线程(三):使用ThreadPoolExecutor创建线程池
1. ThreadPoolExecutor1.2 简介ThreadPoolExecutor 是线程池的管理类,线程池解决了两个不同的问题:由于降低了每个任务的调用开销,线程池通常在执行大量异步任务时提供更好的性能;线程池还提供了一种方法来约束和管理执行任务时消耗的资源(包括线程)。每个ThreadPoolExecutor还维护一些基本统计信息,比如已完成任务的数量。1.2 构造函数说明它提供了以下几种构造函数:corePoolSize: 核心线程数,当线程池调用 submit 提交一个任务并且原创 2020-11-06 17:42:01 · 1094 阅读 · 0 评论 -
Java多线程(二):Callable和FutureTask结合使用获取返回值
1. Callable话不多说,直接上源码:@FunctionalInterfacepublic interface Callable<V> { V call() throws Exception;}跟上一篇讲的 Runnable 一样,Callable 也是一个函数式接口。此外,Callable 还是泛型类,可以指定 call 方法的返回值类型。Callable 源码过于简单,看不出什么,下面我们再介绍一个类:FutureTask2. FutureTask2.1 F原创 2020-11-05 17:39:53 · 1168 阅读 · 0 评论 -
Java多线程(一):Runnable和Thread的基本用法
RunnableRunnable 是个函数式接口,因此可以通过lambda表达式初始化。其内部只有一个run方法,源码比较简单,如下:@FunctionalInterfacepublic interface Runnable { public abstract void run();}Runnable本身做不了什么事情,它主要是作为参数传到Thread的构造函数,由Thread对象来调用。ThreadThread 是 Java 的线程类,它...原创 2020-11-05 15:12:26 · 703 阅读 · 0 评论 -
Java clone浅复制与深复制的区别
概述Java对象要调用 clone 进行复制,必须实现 Cloneable 接口,否则会抛出CloneNotSupportedException的异常。clone 方法默认是浅复制,如果要实现深复制,那必须在clone方法调用对象成员的复制方法。浅复制:复制对象时,对象内部引用类型的成员,仍然共用内存空间。此时A对象修改这个成员的属性,B对象的该成员也会受影响。深复制:复制对象时,对象内部引用类型的成员,也会重新开辟新的空间。此时A对象和B对象完全互不干扰。浅复制cloneGrade: 班级原创 2020-10-29 13:56:56 · 259 阅读 · 0 评论 -
Java进阶:多线程Lock管理多个Condition的实践
概述本篇主要讲解Lock管理多个Condition的情况,对Condition基础还不了解的童鞋,请先看下这篇文章:ReentrantLock和Condition基本使用通过一项需求来实践假设,当前当前有3个任务A、B、C需要按顺序反复地执行。A执行完了执行BB执行完了执行CC执行完了重新执行A用一张图简单画一下就是这样:Condition的等待与唤醒正好可以实现上面这项需求代码实现为了更好地体现控制逻辑,这里代码不做封装,会写得更清晰一点首先,创建一个资源类 MyDatast原创 2020-10-22 22:19:26 · 920 阅读 · 0 评论 -
Java进阶:BlockingQueue阻塞队列的使用
文章目录1. 概述2. 常用的阻塞队列3. 操作方法3.1 抛出异常3.2 特殊值3.3 阻塞3.4 超时1. 概述相比平时讨论的队列,阻塞队列增加了阻塞的功能:当有限长度的队列填满了数据时,继续往队列添加数据的线程将被阻塞住,持续等待,直到超时或队列数据被消费而腾出空间当队列数据为空时,消费线程会因为取不到数据而被阻塞,直到生产线程往队列添加数据,此时成功取到数据而不再阻塞2. 常用的阻塞队列ArrayBlockingQueue:由数组结构组成的有界阻塞队列LinkedBlocking原创 2020-10-21 14:30:41 · 1250 阅读 · 0 评论 -
Java进阶:ReentrantLock和Condition基本使用
1. 概述Java除了使用synchronized锁之外,还可以使用ReentrantLock实现独占锁。ReentrantLock使用起来更加灵活,也提供了更丰富的功能。2. 加锁解锁验证加锁之前,先来看一段没加锁的代码public class ReentrantLockApp { static class MyTest{ public volatile int num = 0; //自增 public void incr(){原创 2020-10-20 22:58:56 · 3358 阅读 · 0 评论 -
Java进阶:default方法说明
1. 概述JDK1.8的接口引入了 static 和 default 方法。static相当于public static修饰,和常规的用法一样,直接通过{类名.方法名}调用。而default方法只有public修饰,必须由接口的实现类来调用。2. default 的作用之所以引入 default ,主要是为了接口的升级。在以往开发中,接口只要增加了方法,所有实现类必须实现该方法,否则编译不通过。而default修饰的接口方法,实现类可以不实现该方法,默认调用接口的default方法实现。3. 示例:原创 2020-10-20 16:09:04 · 9036 阅读 · 0 评论 -
Java进阶:@FunctionalInterface函数式接口使用说明
概述@FunctionInterface 称为函数式接口,属于JDK8新增的特性。常见的一些接口比如Runnable、Callable都添加了该注解。使用要求标记在接口 Interface 上必须包含一个并且只能有一个抽象方法static方法和default方法,都不算抽象方法接口默认继承Object,显示实现例子先看一个错误示例:@FunctionalInterfacepublic interface MyInterface { //第一个抽象方法 void tes原创 2020-10-20 12:20:23 · 1693 阅读 · 0 评论 -
Java进阶:Semaphore信号量基本使用
概述Semaphore 称为信号量,主要用于两个场景1:多个共享资源的互斥使用2:并发线程数的控制Semaphore 实现需求背景:某停车场有3个停车位,现在有6辆车进行抢车位。先抢到车位后停放3秒钟,然后开出停车场,此时剩下的3辆车可以继续抢占车位。代码实现: public static void main( String[] args ) { final int count = 3; //默认是非公平锁,可以使用另一个构造函数,传递公平锁原创 2020-10-19 22:46:58 · 1229 阅读 · 0 评论 -
Java进阶:CyclicBarrier基本使用
概述上一篇文章讲到 CountDownLatch 的用法,CountDownLatch是倒计时直到最后值等于0,才不再堵塞。CyclicBarrier 相反,它主要是做加法的,直到值为某一个值的时候,堵塞才会消失。CyclicBarrier 实现需求背景:当前某部门准备开会,只有当部门全部10个人都到场后,会议才能开始代码实现: public static void main(String[] args) { final int count = 10;原创 2020-10-19 22:20:22 · 1052 阅读 · 0 评论 -
Java进阶:CountDownLatch倒计时
概述CountDownLatch 倒计时器,通常用于堵塞某个线程,直到其他前置线程都执行完毕后,堵塞线程才继续执行。CountDownLatch 是基于CAS实现的,因此它是线程安全的。CAS相关介绍看这篇:Java CAS原理详解举个简单的场景例子:某教室内当前有10个同学,等到所有同学都离开教室后,老师才过来锁门。使用 CountDownLatch 实现 public static void main(String[] args) throws InterruptedExceptio原创 2020-10-19 21:59:46 · 1162 阅读 · 0 评论 -
Java进阶:ReentrantLock实现原理解析(公平锁、非公平锁、可重入锁、自旋锁)
概述本篇将介绍公平锁、非公平锁、可重入锁、自旋锁相关理论知识,然后是ReentrantLock源码解析,最后会做几个Demo来进行验证锁的定义公平锁公平锁是指线程按照申请所的顺序来获取锁,跟队列先进先出一样,排队按顺序获取锁非公平锁非公平锁指的是多个线程获取锁的顺序不一定是申请的顺序,有可能后面申请的线程反而比前面的线程优先获取。非公平锁在申请锁资源时,会先尝试占有锁,成功了就独占锁资源,失败了就进入排队队列高并发环境下,可能会造成优先级反转或者饥饿现象可重入锁自旋锁原创 2020-09-20 19:38:12 · 1814 阅读 · 1 评论 -
Java进阶:图文并茂解析HashMap源码
public V put(K key, V value) { return putVal(hash(key), key, value, false, true); } final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; in...原创 2020-09-19 23:15:22 · 977 阅读 · 0 评论 -
Java进阶:Set、Map线程安全问题
前言前面的博客已经分析了ArrayList线程不安全的原因,以及解决方案,感兴趣的可以参考这里:ArrayList线程安全问题详解。现在这边主要介绍的是Set、Map的线程安全问题SetSet最常用的就是HashSet类型,但是HashSet 是线程不安全的类型,不能用于并发环境。如下这个例子,执行后会抛出java.util.ConcurrentModificationException的异常 public static void main( String[] args ) throw原创 2020-09-19 07:36:11 · 1639 阅读 · 0 评论 -
Java进阶:ArrayList线程安全问题和解决方案
概述ArrayList 是线程不安全的集合类,当多线程环境下,并发对同一个ArrayList执行add,可能会抛出java.util.ConcurrentModificationException的异常例子这边有个简单的程序,创建30个线程,分别对ArrayList执行add操作public class ListApp{ public static void main( String[] args ) throws InterruptedException { List&l原创 2020-09-17 22:41:09 · 2124 阅读 · 0 评论 -
Java进阶:CAS原理详解
概述CAS是Compare And Swap的简称,即:比较并交换Java中常见的是Atomic相关类使用了CAS,例如:AtomicInteger、AtomicBoolean等等实现CAS的底层用的是Unsafe操作类先看个小例子public static void main(String[] args) { AtomicInteger atomicInteger = new AtomicInteger(5); atomicInteger.compareAndSet(5,原创 2020-09-17 16:47:45 · 1037 阅读 · 0 评论