自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(168)
  • 问答 (5)
  • 收藏
  • 关注

原创 非阻塞算法(Lock-Free)的实现

非阻塞算法(Lock-Free)的实现上篇文章我们讲到了使用锁会带来的各种缺点,本文将会讲解如何使用非阻塞算法。非阻塞算法一般会使用CAS来协调线程的操作。虽然非阻塞算法有诸多优点,但是在实现上要比基于锁的算法更加繁琐和负责。本文将会介绍两个是用非阻塞算法实现的数据结构。非阻塞的栈我们先使用CAS来构建几个非阻塞的栈。栈是最简单的链式结构,其本质是一个链表,而链表的根节点就是栈顶。我们先构建Node数据结构:public class Node<E> { public fin

2022-04-30 17:35:13 1408

原创 非阻塞同步机制和CAS

非阻塞同步机制和CAS我们知道在java 5之前同步是通过Synchronized关键字来实现的,在java 5之后,java.util.concurrent包里面添加了很多性能更加强大的同步类。这些强大的类中很多都实现了非阻塞的同步机制从而帮助其提升性能。什么是非阻塞同步非阻塞同步的意思是多个线程在竞争相同的数据时候不会发生阻塞,从而能够在更加细粒度的维度上进行协调,从而极大的减少线程调度的开销,从而提升效率。非阻塞算法不存在锁的机制也就不存在死锁的问题。在基于锁的算法中,如果一个线程持有了锁,那

2022-04-30 17:33:19 431

原创 同步类的基础AbstractQueuedSynchronizer(AQS)

同步类的基础AbstractQueuedSynchronizer(AQS)我们之前介绍了很多同步类,比如ReentrantLock,Semaphore, CountDownLatch, ReentrantReadWriteLock,FutureTask等。AQS封装了实现同步器时设计的大量细节问题。他提供了FIFO的wait queues并且提供了一个int型的state表示当前的状态。根据JDK的说明,并不推荐我们直接使用AQS,我们通常需要构建一个内部类来继承AQS并按照需要重写下面几个方法:t

2022-04-30 17:31:55 555

原创 由于不当的执行顺序导致的死锁

本文将会讨论一下顺序死锁的问题。我们来讨论一个经常存在的账户转账的问题。账户A要转账给账户B。为了保证在转账的过程中A和B不被其他的线程意外的操作,我们需要给A和B加锁,然后再进行转账操作, 我们看下转账的代码:public void transferMoneyDeadLock(Account from,Account to, int amount) throws InsufficientAmountException { synchronized (from){ synchro

2022-04-30 17:29:53 1875

原创 java中有界队列的饱和策略(reject policy)

java中有界队列的饱和策略(reject policy)我们在使用ExecutorService的时候知道,在ExecutorService中有个一个Queue来保存提交的任务,通过不同的构造函数,我们可以创建无界的队列(ExecutorService.newCachedThreadPool)和有界的队列(ExecutorService newFixedThreadPool(int nThreads))。无界队列很好理解,我们可以无限制的向ExecutorService提交任务。那么对于有界队列来说,

2022-04-30 17:28:50 855

原创 万万想不到,线程居然被饿死了

我们在构建线程池的时候可以构建单个线程的线程池和多个线程的线程池。那么线程池使用不当可不可能产生死锁呢?我们知道死锁是循环争夺资源而产生的。线程池中的线程也是资源的一种,那么如果对线程池中的线程进行争夺的话也是可能产生死锁的。在单个线程的线程池中,如果一个正在执行的线程中,使用该线程池再去提交第二个任务,因为线程池中的线程只有一个,那么第二个任务将会等待第一个任务的执行完成来释放线程,而第一个任务又在等待第二任务的执行来完成任务。从而产生了线程饥饿死锁(Thread Starvation Deadloc

2022-04-30 17:28:04 426

原创 使用ExecutorService来停止线程服务

使用ExecutorService来停止线程服务之前的文章中我们提到了ExecutorService可以使用shutdown和shutdownNow来关闭。这两种关闭的区别在于各自的安全性和响应性。shutdownNow强行关闭速度更快,但是风险也更大,因为任务可能正在执行的过程中被结束了。而shutdown正常关闭虽然速度比较慢,但是却更安全,因为它一直等到队列中的所有任务都执行完毕之后才关闭。使用shutdown我们先看一个使用shutdown的例子: public void useSh

2022-04-30 17:26:44 1602

原创 Maven Wrapper简介

简介开发java项目少不了要用到maven或者gradle,对比gradle而言,可能maven要更加常用一些。要使用maven那就必要要安装maven,如果有些用户不想安装maven怎么办?或者说用户不想全局安装maven,那么可以使用项目级别的Maven Wrapper来实现这个功能。如果大家使用IntelliJ IDEA来开发Spring boot项目, 如果选择从Spring Initializr来创建项目,则会在项目中自动应用Maven Wrapper。简单点说就是在项目目录下面会多出两个文件

2022-04-29 16:35:02 1299

转载 新版gitbook导出pdf

最近想把自己写的一个gitbook转成pdf分享出去,突然发现最新的gitbook版本已经不支持导出PDF了。于是在网上找了好久终于被我发现了三个将gitbook转换成pdf的方式,现分享给大家。我使用的是mac系统,如果是其他系统大家可以查找相应的方案。gitbook自带的npm模块gitbooknpm gitbook的最新版本是3.2.3,最新更新时间是1年前,官方估计已经放弃这个模块了。不过还好,这个模块还能够使用。 具体步骤如下:安装npm通常来说,安装好nodejs后会自动安装相应的n

2022-04-29 16:33:57 2700

转载 JDK11的重要新特性

虽然JDK13在今年的9月17号才发布,但是丝毫不会影响到下一个版本JDK14的开发工作。听说官方定的新功能马上就要官宣了,我们这里不妨来提前推断一下。在9月17号的发布中,Oracle提到了switch表达式的功能预计会在JDK14中最终确定。在我的之前的文章中我已经提到了,在JDK12和JDK13中switch表达式都是作为一个实验性的语法来推出的,经过三个版本的迭代,switch表达式的正式推出该是顺理成章的事情了。同时也会包含一个JDK Enhancement Proposal (JEP)的更新

2022-04-29 16:32:36 700

转载 JDK11的重要新特性

JDK11发布啦JDK11 在2018年9月25发布。它是一个LTS版本。这就意味着这,我们会从JDK8直接升级到JDK11。那么JDK11有些什么变化呢?就我看来,JDK11最大的变化就是删除。Oracle不再提供JRE和Server JRE下载先前的发行版有两种类型的运行时映像:JRE是Java SE Platform的完整实现,而JDK则将整个JRE包含在jre/目录中,还包括开发工具和库。在JDK11中,JRE已经被删除了,这意味着后面要下载只有一个JDK可以下载了。用户可以使用jlin

2022-04-29 16:26:17 828

转载 JDK12的五大重要新特性

JDK12的五大重要新特性Java12在March 19, 2019发布了。在2017年发布Java 9之后,Java平台发布节奏已从每3年以上的主要版本转变为每6个月发布一次功能。现在,每年的3月和9月都会发布新的版本功能。 从而提供了更细化,更快和可管理的版本更新。这是一个好消息,不好的就是大家会觉得JDK的版本更新太快了。什么?JDK12已经出来了?什么?9月份要出JDK13了?什么?我还在用JDK8?废话少说,我们来看下JDK12的五个比较重要的新特性:引入JVM常量API扩展了

2022-04-29 16:25:19 2607

转载 JDK13的六大重要新特性

JDK13的六大重要特性JDK13在9月17号全球首发了,Oracle JDK 13通过改善Java SE平台和JDK的性能,稳定性和安全性来提高开发人员的生产力。这次的JDK13包含了5个JEP(Java Enhancement Proposals)和一个Unicode 12.1的支持总共6大主要新特性。下面我们一一详细说明。支持Unicode 12.1动态CDS归档(Dynamic CDS Archiving)java.net.Socket和java.net.ServerSocket API的

2022-04-29 16:20:51 1063

转载 Java函数式编程和Lambda表达式

什么是函数式编程相信大家都使用过面向对象的编程语言,面向对象编程是对数据进行抽象,而函数式编程是对行为进行抽象。函数式编程让程序员能够写出更加容易阅读的代码。那什么时候函数式编程呢?函数式编程是一种编程的方法论,主要是将行为编写成一个个的函数。什么是函数?函数就是对输入的值进行处理,返回另外的值。Lambda表达式在Java 8 中引入的Labmda表达式是函数式编程的一种实现。什么是Lambda表达式呢?我们举个例子下面的代码如果使用Java 7 的话应该这样写: //sort us

2022-04-29 16:16:10 477

原创 java~优先级队列PriorityQueue

概念PriorityQueue是一种支持排序的优先级队列,你入队列的对象需要实现Comparable或Comparator接口,或者它本身支持自然排序,如Integer,Long这些类型(这些类型也都实现了Comparable接口)。数据结构优先级队列底层的数据结构其实是一颗二叉堆,什么是二叉堆呢?我们来看看下面的图(a为大顶堆,b为小顶堆)在这里我们会发现以下特征:二叉堆是一个完全二叉树根节点总是大于左右子节点(大顶堆),或者是小于左右子节点(小顶堆)。java代码例子定义一个

2022-04-27 10:48:35 192

原创 java~http获取内存缓慢解决方法

情况使用hutool的HttpUtil来获取远程的网页,类似爬虫,获取到的内容是GBK的,我们把它直接使用response.charset(“UTF-8”);最后输出body()之后发现是乱码工具 <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.5.7</ver

2022-04-27 10:47:38 331

原创 java~并行计算~大集合的并行处理

本讲主要结合实际应用,来封装一个集合并行处理组件,我们的集合分为数据库查询出现的分页集合;还有一个是内存的集合,今天主要说一下内存集合的并行处理。场景介绍有一个比较耗时的工作,将top 400的用户的行为信息统计统计的信息来自很多业务,很多服务,不能使用聚合直接计算这些业务统计的时间,大概每个人平均需要1秒这些用户的各种类型,彼此独立,没有关系如何设计如果直接顺序写代码,那1万的用户,需要400秒的时间,这是我们不能接受的,我们使用并行编程8秒就把它搞定。如何实现400的集合,进行拆

2022-04-27 10:47:03 923

原创 keycloak~大数据量时坑出现~索引的坑

我不知道为什么kc没有为对应的查询字段加索引,导致我们在使用kc时,当用户表数据量达到几十万时,出现所有增删改接口缓慢的问题,这个问题的原因,我找了好长时间,我在大数据量时找这个缓慢原因过程查看mysql的并发数的限制查看top产生的cpu,内在的使用情况查看客户端到kc端,kc端到数据库的网络传输限制为k8s的资源进行调整,添加内存额度为username字段添加索引打开mysql日志功能,观察慢接口的日志找到慢的语句select userentity0_.ID as ID1_75_, us

2022-04-27 10:46:09 535

原创 java~使用枚举来实现接口的多态

java的enum类型,与C#不一样,它就是一个类,它可以实现接口,并且,可以通过的不同的枚举值来实现一个接口,这就是枚举的多态性。下面的例子,在Hello接口有方法print,在枚举Strategy中,通过不同的枚举值分别实现了Hello接口,如下代码 enum Strategy implements Hello { CHINA() { @Override public void print() {

2022-04-27 10:45:30 748

原创 keycloak~扩展事件机制,集成kafka中间件

对于KC的后台或者接口的操作,当用户,组,角色这些实体状态发生改变时,KC会对外发布事件,而这些事件处理程序我们是可以在后台配置的,默认继承了jboss-logging日志事件,而我们可以在事件管理中去配置自己的事件处理程序。事件处理程序SPI实现EventListenerProviderFactory和EventListenerProvider这两个SPI即可,我们在这里可以订阅由KC发出现的事件,针对我们感兴趣的事件,去添加处理代码。/** * 后端管理平台事件 *

2022-04-27 10:42:45 307

原创 springboot~连接kafka需要注意的地方

kafka需要zookeeper的支持,我们可以使用docker-compose简单的部署一个环境,在部署时,kafka需要我们为它配置一个hostname,这个名称是每个kafka节点(broken)的名称,也是很容易被忽视的地方,通过kafka客户端工具可以看到你当前部署kafka时的hostsname,在部署java时,你的主机也需要配置这个host.部署一个kafkadocker-compose实现version: '2'services: zookeeper: image

2022-04-27 10:40:50 478

原创 keycloak~自定义SPI的注入与扩展

项目结构自定义SPI注册1. 直接复制文件方式docker cp keycloak-service-self-spi.jar keycloak:/opt/docker cp module-one-add.cli keycloak:/opt/docker exec -it keycloak bash$JBOSS_HOME/bin/jboss-cli.sh --file=/opt/module-one-add.cli使用docker commit保存你当前容器为一个新的镜像,然后启动它即可

2022-04-26 11:59:45 3074 1

原创 springboot~feign模拟multipart/form-data

openfeign介绍在微服务设计里,服务之间的调用是很正常的,通常我们使用httpClient来实现对远程资源的调用,而这种方法需要知识服务的地址,业务接口地址等,而且需要等他开发完成后你才可以去调用它,这对于集成开发来说,不是什么好事 ,产生了A业务与B业务的强依赖性,那么我们如何进行解耦呢,答案就是openfeign框架,它与是springcloudy里的一部分。    springcloud的服务消费者指的就是服务间的调用,实现的方式有两种:一种就是上一章讲的restTemplate+ribbo

2022-04-26 11:58:24 2724

原创 基础才是重中之重~BouncyCastle实现的DES3加密~java通用

对于BouncyCastle类库(包)来说,他提供了很多加密算法,在与.net和java进行相互加解密过程中,得到了不错的应用,本文以DES3为例,来说一下DES3加解密的过程。加密过程明文字符转为byte数组对密钥进行处理,处理后一般为16或者24字节对明文进行DES3加密,生成密文的byte数组对密文byte数组进行base64的编码解密过程对密文byte数组进行base64的解码对密钥进行处理,处理后一般为16或者24字节对解码后的byte数组进行DES3解密对解密之后的by

2022-04-26 11:55:35 636

原创 jenkins~Publish Over SSH实现分布式部署

如果你的项目分布在不同的服务器上,在jenkins构建完成之后,就需要将代码推到目标服务器上运行了,这就用到了Publish Over SSH插件。配置在jenkins配置里-》系统配置里,对Publish Over SSH的服务器节点进行添加,这个插件如果没有需要先安装。这里比较重要的是配置目标服务器的根路径,然后在job里目标路径都是基于这个根路径的使用需要注意,你的源文件路径应该是jenkins默认工作区下的路径,这个是必须的如果是当前文件夹下所有文件,可以使用如下方法在此我向大家

2022-04-26 11:54:41 220

原创 maven~为MANIFEST.MF文件添加内容

MANIFEST.MF打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息,下面将详细介绍MANIFEST.MF文件的内容。公共内容Manifest-Version 用来定义manifest文件的版本,例如:Manifest-Version: 1.0Created-By 声明该文件的生成者,一般该属性是由jar命令行工具生成的,例如:Created-By: Apache Ant

2022-04-26 11:52:58 674

原创 maven~多个plugin相同phase的执行顺序

对于maven进行项目构建时,我们会使用到插件,对构建过程进行一些控制,加工,加密,重写,依赖打包等工作,一般我们打包时会把phase定为package,意思是说,当进行package动作后,处理你的插件。多个相同phase的顺序当我们有多个plugin,并且相同phase时,有时需要考虑到顺序问题,因为你的plugin可能会有某个其它plugin的结果的依赖,所以我们需要控制<plugins> <plugin> <artifactId>maven-sha

2022-04-26 11:49:24 2998

原创 java~jar防止反编译

对于jar包,如果是为客户私有化部署的,会将jar包给客户,这时就会有源代码泄露的风险,你的一些加密算法,密钥就公开了,所以我们需要为jar包进行加密,或者叫字节码混淆。classfinalclassfinal是一个字节码混淆工具,我们可以直接把它集成到maven里,以插件的形式去使用它,下面是配置文件 <plugin> <groupId>net.roseboy</groupId>

2022-04-26 11:48:28 1552

原创 springboot~为ES实体封装审计Auditing功能

审记功能在Jpa框架里出现的,主要针对实体的几个字段进行自动化的赋值,让业务人员可以把关注点放在业务上,对于公用的,有规则的字段,由系统帮我们去处理。原理通过spring aop功能实现对es仓库接口方法的拦截,然后在方法处理之前,为实体的这些公用字段赋值即可,我们使用了jpa里的一些注解,如@CreateBy,@CreateDate,@LatestModifyDate等等。EsBaseEntity实体@Datapublic class EsBaseEntity { public sta

2022-04-25 18:16:53 435

原创 springboot~使用自定义的aspect

对某个类型中的方法进行拦截,然后加入固定的业务逻辑,这是AOP面向切面编程可以做的事,在springboot里实现aop的方法也有很多,spring-boot-starter-aop或者aspectjweaver都是可以实现的,不过我们在实现之前,先来看一下aop里的几个概念。概念切面(Aspect):是指横切多个对象的关注点的一个模块化,事务管理就是J2EE应用中横切关注点的很好示例。在Spring AOP中,切面通过常规类(基本模式方法)或者通过使用了注解@Aspect的常规类来实现。连接

2022-04-25 18:15:43 4122

原创 shade解决mybatis包冲突~项目引用的方法

今天主要说一下在项目里如何引用这个包。1 如果只是使用包里的资源,而不使用这个包的依赖包,需要这样引用即可 <dependency> <groupId>com.lind</groupId> <artifactId>a-start-test-depend-shade</artifactId> <version>1.0.4</version>

2022-04-25 18:14:46 166

原创 springcloud~nacos在使用中需要注意的问题

配置文件问题如果使用application命名时,需要使用Properties扩展名的,如果使用yml格式的,那你不能使用application.yml,而应该使用bootstrap.yml这种格式,如图所示,这种是无法加载配置的使用bootstrap然后定义好扩展名,因为在nacos里我们添加的是yaml文件,,只它默认只查询 properties文件bootstrap.ymlserver.port: 6060spring: application.name: gateway p

2022-04-25 18:13:45 577 1

原创 springboot~nexus项目打包要注意的地方

一个使用maven制作框架包时,会有一个主项目,然后它有多个子项目框架组成,很少一个工具包一个工程,像springboot,springcloud都是这种结构,主项目用来管理一些依赖包的版本,这对于框架型项目来说是很必要的,而对于业务项目来说,因为目前都是推荐使用微服务的轻量方式,所以不建议用多项目绑定一个大项目的方式,而都是一个服务一个项目。主pom文件主项目的pom文件用来管理依赖包版本,一般在dependencyManagement节点去声明它们的版本号,这样在子项目里可以不声明相同包的版本信息

2022-04-25 18:12:33 470

原创 springboot~DTO字符字段与日期字段的转换问题

不会自动转换string与date主要是这个意思,前端提交的JSON里,日期是一个字符串,而对应后端的实体里,它是一个Date的日期,这两个在默认情况下是不能自动转换的,我们先看一下实体实体public class UserDTO { private String name; private String email; private Boolean sex; private Double total; private BigDecimal totalMoney

2022-04-25 18:10:40 1878

原创 springboot~maven多项目同时启动的配置

maven多项目启动在多项目的maven项目里,你可以通过配置.idea/workspace.xml来配置多项目同时启动,这样方便于你的调试,不需要一个一个的启动了workspace.xml文件里添加<component name="RunDashboard"> <option name="configurationTypes"> <set> <option value="SpringBootApplicationConfiguratio

2022-04-25 18:05:16 1018

原创 springboot~gradle4.7之后的lombok引用方法

在gradle4.7以后对于加入依赖lombok方式发生变化,gradle4.7版本以前,可以直接如下引用:在gradle4.7版本以后甚至现在gradle5.0了里面这种方式会产生警告,在gradle5.0里面会直接报编译错误。正确使用可以采用如下两种方式:1.官方推荐方式开发依赖:测试依赖:目前官方也是比较推荐这种方式来引用lombok库!在此我向大家推荐一个架构学习交流圈。交流学习微信:539413949(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spri

2022-04-24 17:05:46 742

原创 rabbitmq~消息失败后重试达到 TTL放到死信队列(事务型消息补偿机制)

这是一个基于消息的分布式事务的一部分,主要通过消息来实现,生产者把消息发到队列后,由消费方去执行剩下的逻辑,而当消费方处理失败后,我们需要进行重试,即为了最现数据的最终一致性,在rabbitmq里,它有消息重试和重试次数的配置,但当你配置之后,你的TTL达到 后,消息不能自动放入死信队列,所以这块需要手工处理一下.rabbitmq关于消息重试的配置 rabbitmq: host: xxx port: xxx username: xxx password: xxx

2022-04-24 16:57:42 916

原创 springboot+k8s+抛弃springcloud.eureka

springboot开发微服务框架一般使用springcloud全家桶,而整个项目都是容器化的,通过k8s进行编排,而k8s自己也有服务发现机制,所以我们也可以抛弃springcloud里的eureka,而直接使用k8s自己的服务。添加组件<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-rib

2022-04-24 16:55:32 2442 1

原创 config-server-bus动态更新配置

config-server用来搭建配置中心,而配置信息一般使用gitlab仓库来存储,这样在你的配置发生改变时,不需要从新打包,而如果使用native的试,则需要从新打一个config-server的jar包。配置的热更新当你的服务的配置信息发生改变时,一般来说需要从新重启你的服务,配置信息才能生效,这对于我们来说是不友好的,所以springcloud有一种消息总线的方式来实现配置信息的热更新,更你的服务不需要从新启动。项目搭建eureka-server<dependency>

2022-04-24 16:53:20 981

原创 springboot~maven集成开发里的docker构建

统一设计maven很好的把项目整合在一起,在部署时,每个项目可以有自己的Dockerfile,在构建后把对应的jar包复制到Dockerfile的同级目录,使用使用统一的打包镜像和容器启动方法去执行就可以了。需要大maven根项目添加插件 <build> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifac

2022-04-24 16:50:26 1425

空空如也

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

TA关注的人

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