![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java
文章平均质量分 64
Leo Han
Leo Han
展开
-
git回滚reset到指定分支
git回滚到指定分支,reset 分支原创 2022-10-17 16:20:51 · 1242 阅读 · 0 评论 -
从底层了解JVM的volatile实现,CPU Cache、缓存一致性MESI、Store BufferI、nvalidate Queue等知识
JAVA中volatile底层原理原创 2022-07-16 17:57:22 · 597 阅读 · 0 评论 -
java中String,StringBuilder,StringBuffer实现原理,优化
java中String,StringBuilder,StringBuffer实现原理原创 2022-06-28 18:35:44 · 427 阅读 · 0 评论 -
java中异步调用,Callable,Future,FutureTask,CompletableFuture如何使用
我们知道,在java中一般多线程编程时经常会使用Thread或者Runnable来进行自定义的线程运行逻辑,但是如果我们需要在一个线程运行结束时返回给另外一个线程结果,上面两个实现都不是很容易实现,一般可能需要另外的实现,比如通过一个临时变量共享。在java中,提供了Callable能够返回结果的线程方法调用。我们看一下下面这个实现: ExecutorService executor = Executors.newFixedThreadPool(2); Callable<Stri原创 2022-05-19 15:52:45 · 1154 阅读 · 0 评论 -
java中wait,notify,notifyAll,sleep方法的作用和区别
在进行多线程编程时,进程会遇到多线程之前的同步已经等待场景。在java中,Object类提供了wait、nofity、notifyAll用来进行线程间的同步。一般如果我们调用wait、nofity、notifyAll都是结合synchronized同步关键字来使用: new Thread(()->{ synchronized (monitor){ try { System.out.println("1原创 2022-05-17 19:26:42 · 342 阅读 · 0 评论 -
java并发控制类之CountDownLatch、CyclicBarrier、Semaphore
java并发包中提供了CountDownLatch、CyclicBarrier、Semaphore这三个类可以来实现一些线程之间的状态同步。这三个本质上都是基于java并发包的AQS来实现的。CountDownLatch首先来看CountDownLatch,其可可以让一个线程等待其他线程都执行完之后才开始执行。其典型用法如下: CountDownLatch countDownLatch = new CountDownLatch(3); new Thread(new Runnable()原创 2022-02-23 14:50:43 · 330 阅读 · 0 评论 -
java中String.format输出%
在java中,很多时候我们都会使用String.format对一些字符串进行拼接或者格式化处理,比如:String.format(" AND %s = '%s'",colName,value);但是如果我们想生成比如类似SQL中like语句:String.format(" AND %s = '%%s%'",colName,value);如果按照上述写法,会报错,java.util.UnknownFormatConversionException,这时候需要对%转义,将要输出%的地方换成两个%即可原创 2022-01-27 17:29:03 · 2646 阅读 · 0 评论 -
java同步之线程池ThreadPoolExecutor实现原理
一般我们在java编程时为了提供程序的性能,很多时候会借助CPU多核优势,进行多线程处理,将一个大任务分给多个线程并发处理,加速处理速,而java默认提供了几种线程池实现:Executors.newFixedThreadPoolExecutors.newCachedThreadPoolExecutors.newSingleThreadExecutor()Executors.newScheduledThreadPool而这些线程池的实现,底层大部分都是基于ThreadPoolExecutor,我原创 2022-01-25 17:32:54 · 862 阅读 · 0 评论 -
java同步阻塞队列之SynchronousQueue
SynchronousQueue是一个比较独特的队列,其本身是没有容量的,比如我放一个元素到队列中去,不能立马返回,必须要等有人消费了这个元素之后才能返回。SynchronousQueue底层,提供了两种数据结构,队列和栈,实现了公平调度和非公平调度。其内部有一个接口Transferer是其实现的基础: abstract static class Transferer<E> { abstract E transfer(E e, boolean timed, long nan原创 2022-01-25 11:28:32 · 1228 阅读 · 0 评论 -
java同步阻塞队列之DelayQueue实现原理,PriorityQueue原理
DelayQueue是一种延迟队列,能够在指定的时间之后执行。其底层采用PriorityQueue作为底层数据结构。在讲解DelayQueue之前,我们需要先讲解一下PriorityQueue。PriorityQueue是一个优先级队列,在底层使用了一个可动态扩容的数组作为基础数据结构,实现了堆结构,默认是一个小顶堆。public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Ser原创 2022-01-24 16:23:23 · 475 阅读 · 0 评论 -
java同步阻塞队列之LinkedBlockingQueue实现原理,和ArrayBlockingQueue对比
上一篇我们说到ArrayBlockingQueue,底层是数组加锁机制实现同步阻塞队列,这里我们说下另外一个同步阻塞队列LinkedBlockingQueue.从名字上就可以看出LinkedBlockingQueue底层数据结构是基于链表结构的。我们看下其几个关键属性: private final int capacity; private final AtomicInteger count = new AtomicInteger();transient Node<E> head;原创 2022-01-24 14:53:55 · 2790 阅读 · 0 评论 -
java同步阻塞队列之ArrayBlockingQueue实现原理
在java中我们可以用同步阻塞队列实现生产者-消费者模型。ArrayBlockingQueue提供了阻塞队列功能,底层数据结构是基于数组,提供如下几个关键方法:public boolean add(E e) 向队列中添加元素底层调用的是offer方法,如果添加成功返回true,否则抛出IllegalStateException异常public boolean offer(E e),向队列中添加元素,如果队列 已经满了,返回false,否则添加元素public void put(E e) throw原创 2022-01-21 17:01:41 · 867 阅读 · 0 评论 -
java并发之ReentrantLock.Condition实现原理
一般我们在实际开发过程中经常会遇到一种情况需要在满足一个条件才能继续,比如我们使用生产-消费模型的时候,消费服务必须有数据消费,如果没数据则等待,当生产线程产生数据的时候,唤醒消费线程。示例代码如下:ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition(); new Thread(()-> { try原创 2022-01-21 15:42:45 · 715 阅读 · 0 评论 -
java中HashMap和ConcurrentHashMap实现原理,LinkedHashMap和TreeMap有序
在java中,HashMap底层是通过 数组 + 链表实现的,如果当某个链表元素个数超过8个,则链表转化为红黑树。其底层类似上述结构,一层采用数组结构,每个数组里面都是一个链表,当我们进行put的时候,计算key的hash值,和数组的长度-1取余得到待添加元素在数组中的位置,然后看该位置是否有元素,如果没有元素,那么作为链表的头加入,如果有,加入到已有的链表中,如果链表的元素超过8个,这时候将链表转换为红黑树。 transient Node<K,V>[] table;static fi原创 2022-01-13 17:24:46 · 783 阅读 · 1 评论 -
java中ReentrantLock实现,公平锁和非公平锁,AQS并发队列,
一般在java中,遇到并发的时候,我们很多时候可能会使用synchronized关键字来实现锁,但是synchronized关键字有一定的缺陷(比如无法实现类似读锁、非公平),而Lock可以实现。在java中常用的有ReentrantLock,我们看下实现,一般我们在代码中如下方式来调用锁: ReentrantLock lock = new ReentrantLock();lock.lock();xxxxxx lock.unlock();这里默认的是非公平锁,可以在构造ReentrantLock原创 2022-01-11 17:17:37 · 809 阅读 · 0 评论 -
设计模式研究,java 23种设计模式
众所周知,我们在实际编写代码时,为了更好的组织代码,都会在代码中采用的一定的设计模式。一般我们在代码的设计中会遵循如下几大原则:开闭原则(OCP open closed Proiciple),一个类应该对扩展开放,对修改关闭单一职责原则(SRP single responsibility prociple)依赖倒置原则(DIP depedence inversion principle),实际上就是要依赖于抽象,高层模块不应该依赖于底层模块,二者应该依赖于抽象;抽象不应该依赖于具体实现,具体实现应该原创 2021-12-29 16:40:33 · 725 阅读 · 0 评论 -
java中Class<T> 和Class<?>
在java中类型Class是一个很重要的概念,用来表示一个类对应的具体类型,T bean,;Class clsT;Class<?> clasGeneric;上面T表示的是一个具体的类型,而Class 和Class<?> 则代表这个类型对应的类Class<?>这是一个类型通配泛型,表示可以表示任何类,如果要加上限定可以通过如下方式:Class<? extends T> 表示是T的一个未知子类型Class<? super T> 表示原创 2021-12-20 14:44:13 · 2970 阅读 · 0 评论 -
Raft算法实现 - Sofa-JRaft,选主,数据写入,日志复制
关于raft算法相关细节,可以全看之前的文章 分布式一致性算法,两阶段提交,三阶段提交,Paxos,Raft,zookeeper的选主过程,zab协议,顺序一致性,数据写入流程,节点状态,节点的角色这里我们说下阿里开源的sofa-jraft的实现。首先说明下,在sofa-jraft有几个比较重要的角色Node 代表的就是一个服务节点Ballot 代表的是一次投票的相关信息PeerId 代表的是一个复制组里面的一个参与角色JRaft的投票有两个步骤preVote和vote,之所以要增加一个pr原创 2021-12-02 11:16:20 · 3266 阅读 · 0 评论 -
高性能队列Disruptor使用入门,原理和代码实现
网上有不少关于Disruptor的文章,这里聊聊自己的看法。我总结Disruptor高性能的实现在于如下几点:缓存行填充对齐无锁CAS操作异步并发消费1. 缓存行填充对齐一般我们知道在我们程序运行的时候,内存访问都是比较快速的,但是CPU并不和内存打交道,而是和寄存器,当CPU要读取数据时,从内存中将数据加载到寄存器中,CPU的每个核心都有一个专属的寄存器,但是寄存器受限于成本,一般容量比较小,后来人们又在寄存器和内存中增加了所谓的L1,L2,L3三级缓存,当CPU要访问一个数据的时候,首先原创 2021-11-29 21:59:41 · 1031 阅读 · 0 评论 -
java8中stream().collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator)说明
java8中提供了Lambda表达式,常用的操作如下:list.stream().collect()来进行操作,collect中传入的参数如下:<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);Supplier 提供容器,供后续ac原创 2021-05-12 18:12:51 · 1715 阅读 · 2 评论 -
Linux中crontab调用java时,无法找到java命令,log4j日志无法查看
首先,在linux中crontab定时执行任务的时候,其环境变量并不是我们登陆用户时的环境变量,所以,我们在crontab定时执行任务的脚本里面,可以加入:source /etc/profile或者在脚本中首行:#!/bin/bash -l表示以login shell的方式登陆java程序log4j日志文件不显示,其实并不是没有显示,而是一般我们设置log4j文件的位置时都是以相对位置,一般会在crontab用户的home目录下面,我们可以在定时任务的执行脚本中执行java之前增加如下:pa原创 2020-08-03 15:25:30 · 940 阅读 · 0 评论 -
Idea下单元测试覆盖率统计
有时候我们需要统计项目单元测试的覆盖率,这时候我们可以借助Idea来实现,测试采用的是 Idea 2019.3.选择 Run ⇒ Edit Configurations …原创 2020-07-14 10:25:26 · 4831 阅读 · 1 评论 -
java中反射桥接方法Method.isBridge
java在1.5带来了泛型操作,但是在虚拟机底层字节码而言,只有普通方法和变量,没有泛型这一说,为了实现相关功能:public interface IHello<T> { public void sayHello(T t);}public class HelloWorld implements IHello<String> { @Override public void sayHello(String s) { System.out.pr原创 2020-06-27 13:42:45 · 280 阅读 · 0 评论 -
悲观锁,乐观锁,公平锁非公平锁,独占锁,共享锁,可重入锁,自旋锁
悲观锁:认为数据很容易被修改,所以数据处理前先对数据进行加锁,在整个处理过程中,数据一直处于锁定状态,其他线程这时候想要拿到锁,必须阻塞等待乐观锁:乐观锁是相对悲观锁来说的,认为数据在一般情况下不会被修改,在访问记录前不会加锁,在对数据进行提交更新时,才会正式判断数据是否发生改变并返回对应信息,让用户自己决定怎么处理,一般通过版本号和CAS来实现。公平锁与非公平锁:根据线程抢占锁的机制,公平锁表示线程获取锁的顺序是按照请求锁的时间的早晚来决定的,即谁先来谁先获取,非公平锁则并不是,并不按照先后时间来决定原创 2020-05-10 21:46:44 · 1381 阅读 · 0 评论 -
java中线程安全,volatile,synchronized,锁,线程同步,锁的状态和锁升级,CAS ABA,happens-before
在说线程之前,首先必须要说的一个概念是进程,任何线程不能独立存在,进程只操作系统结构的基础,是代码在数据集上的一次运行活动,是系统进行资源分配和调度的一个独立单位,线程可以理解为是进程的子任务,是进程的一个执行路径,进程中的多个线程共享进程的资源。我们知道CPU执行是给每个线程分配CPU时间片来执行线程业务,时间片是CPU份额配给各个线程的时间,非常短,CPU通过不停切换线程执行,充分利用CPU和发挥CPU多核。这里就存在一个问题,CPU在线程之间来回切换执行,切换到之前执行的线程,如何继续执行下去,所以每原创 2020-05-10 16:37:59 · 208 阅读 · 0 评论 -
java连接mysql,jdbc驱动
maven依赖:<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.36</version> </dependency>示例代码:import java.sql.Connect原创 2020-05-09 14:26:40 · 153 阅读 · 0 评论 -
java连接sqlserver,mssql,jdbc驱动
首先添加maven依赖: <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>sqljdbc4</artifactId> <version>4.0</versi...原创 2020-05-08 12:29:22 · 864 阅读 · 0 评论 -
java连接PostgresSQL,JDBC驱动
Java连接PostgresSQL代码示例:添加maven依赖: <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <versi...原创 2020-05-08 12:23:58 · 1751 阅读 · 0 评论 -
java连接impala,jdbc,带kerberos认证登录
添加依赖: <dependency> <groupId>com.cloudera.impala</groupId> <artifactId>jdbc</artifactId> <version>2.5.31</version> ...原创 2020-05-06 14:24:17 · 1533 阅读 · 0 评论 -
Postgresql中invalid byte sequence for encoding \"UTF8\": 0x00".
由于目前Postgresql中官方解释Postgresql对于0x00和\u0000无法支持,必须进行替换。在java中尝试程序将SQLServer程序导入到Postgreslq中时,发生上述问题,解决办法是: public String transfer0x00(String str){ if(str !=null && str.indexOf(0x00) &...原创 2019-03-13 14:11:18 · 8563 阅读 · 3 评论 -
tomcat8开启APR
Tomcat8中开启APR需要安装apr和apr-util,具体步骤如下:下载 apr-1.6.2和apr-util-1.6.1需要的几个环境#yum -y install autoconf // 安装autoconf#yum -y install libtool // 安装libtool#yum -y install openssl openssl-devel // 安装op...原创 2018-08-16 18:25:33 · 1223 阅读 · 0 评论