Java
文章平均质量分 72
java
CodingAnHour
明日复明日,明日何其多。我生待明日,万事成蹉跎。
展开
-
Java 独占锁ReentrantLock、读(悲观读)写锁ReentrantReadWriteLock、读(乐观读/悲观读)写锁StampedLock
锁必然要知道AbstractQueuedSynchronizer(AQS),AQS提供了一个框架,用于实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量、事件等)。独占,只有一个线程能执行,如ReentrantLock(悲观锁:除非线程1全部运行完后才会释放锁,否则其他线程无法拿到锁。可重入,公平与非公平特征 )Lock是juc中实现的锁接口,定义了锁的一些行为规范,他的设计目的是为了解决synchronized关键字在一些并发场景下不适用的问题,相对synchronized更灵活。....原创 2022-08-28 10:53:08 · 530 阅读 · 0 评论 -
数据结构与算法(一)复杂度
代码效率优化方法论复杂度:如何衡量程序运行的效率数据结构:将“昂贵”的时间复杂度转换成“廉价”的空间复杂度复杂度:如何衡量程序运行的效率复杂度是什么复杂度是衡量代码运行效率的重要的度量因素。在介绍复杂度之前,有必要先看一下复杂度和计算机实际任务处理效率的关系,从而了解降低复杂度的必要性。计算机通过一个个程序去执行计算任务,也就是对输入数据进行加工处理,并最终得到结果的过程。每个程序都是由代码构成的怎么衡量复杂度实际衡量时,我们通常会围绕以下2 个维度进行。首先,这段代码消耗的资源是什么原创 2020-07-12 23:51:15 · 451 阅读 · 0 评论 -
Java集合Set之源码HashSet、LinkedHashSet
HashSet 底层是HashMap添加一个元素时,先得到hash值会转成->索引值找到存储数据表table,看这个索引位置是否已经存放的有元素如果没有,直接加入如果有,调用 equals 比较,如果相同,就放弃添加,如果不相同,则添加到最后判断当前key与p节点的值是否相等,相等则是同一个值(注意,equals方法每个类都可以重写,具体判断各不相同)在Java8中,如果一条链表的元素个数到达 TREEIFY_THRESHOLD(默认 是8),并且table的大小>= MIN.原创 2021-12-18 09:30:43 · 588 阅读 · 0 评论 -
Java数据库树型层级存储结构特殊的应用场景比parentId更好用
数据库存储结构A000B000C000D001E002需要存储当前层级的字母(比如E),所属层级全路径如(A000B000C000D001E002)每个跟节点的最大叶子节点大小取决于字母后的数值大小num满树的最大值:树深度m,最大值= numᵐ+1优点随时查询每个层级的数据,不需要像以往根据parentId逐层查询效果如图:/** * 多叉树 的形式记录上下级 * @param args */public static void main(String[] args) {.原创 2021-12-03 10:10:53 · 952 阅读 · 0 评论 -
并发编程(十一)什么是队列、常用的队列
1、什么是队列Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构,类似火车站排队买票。从图中可以看出,Queue接口与List、Set同一级别,都是继承了Collection接口。2、队列的常用方法2.1、Queue中方法简述方法操作说明是否抛异常add增加一个元素当队列长度限制,抛出 IllegalStateException,更推荐使用offeroffer添加一个元素当队列长度限制,达到上限,会抛出异常remove如果该队列包含一原创 2021-08-29 17:38:22 · 304 阅读 · 0 评论 -
并发编程(十)ThreadPoolExecutor源码分析、拒绝策略、队列、示例代码
1、为什么用ThreadPoolExecutor创建线程池虽然jdk中Executor框架提供了如newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()等创建线程池的方法,但都有其局限性,不够灵活;另外由于前面几种方法内部也是通过ThreadPoolExecutor方式实现,使用ThreadPoolExecutor有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险。如果大家开发中使用《原创 2021-08-22 15:37:31 · 359 阅读 · 0 评论 -
并发编程(九)Executors线程池
1、什么是线程池线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源,因此Java中提供线程池对线程进行统一分配、 调优和监控2、为什么使用线程池在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理。如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题: 如果并发的请求数量非原创 2021-08-15 22:51:37 · 225 阅读 · 0 评论 -
并发编程(八)Thread源码分析,方法示例
1、Thread类是什么Java中Thread类用来实现线程编程什么是线程、什么是进程、为什么用到并发可以查看我的并发系列第一篇文章《并发编程(一)为什么用并发编程、JMM内存模型、volatile、内存屏障》2、线程的状态new java.lang.Thread().start()只有调用start()方法的时候,才会真正的在 JVM中去创建线程。线程从创建到最终的消亡,要经历若干个状态。一般来说,线程包括以下这几个状态:创建:new运行:runnable(运行中:running、就绪:r原创 2021-08-15 00:45:40 · 328 阅读 · 0 评论 -
并发编程(六)原子操作 java.util.concurrent.atomic
1 什么是原子操作“不能被进一步分割的最小粒子”,原子操作(atomic operation)即”不可被中断的一个或一系列操作”。在多处理器上实现原子操作就变得有点复杂。名称英语解释缓存行Cache line缓存的最小操作单位比较并交换 CAS(无锁的)Compare and SwapCAS操作需要输入两个数值,一个旧值(期望操作前的值)和一个新值,在操作期间先比较下在旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换。CPU流水线CPU原创 2021-07-28 00:18:50 · 343 阅读 · 0 评论 -
&、|、~、^、<<、>>、<<<、>>>、高几位,低几位
&:按位与运算符:参加运算的两个数据,按二进制位进行“与”运算。两个位都为1时,结果才为1运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;|:按位或运算符:参加运算的两个对象,按二进制位进行“或”运算。两个位都为0时,结果才为0运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1;~:取反运算符:参加运算的一个数据,按二进制位进行“取反”运算。0变1,1变0运算规则:~1=0; ~0=1;^:异或运算符:用于比较两..原创 2021-07-24 17:44:36 · 541 阅读 · 0 评论 -
Java集合List之源码LinkedList
LinkedList的特点LinkedList是通过双向链表去实现的。从LinkedList的实现方式中可以看出,它不存在容量不足的问题,因为是链表。LinkedList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写出“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。LinkdedList的克隆函数,即是将全部元素克隆到一个新的LinkedList中。由于LinkedList实现了Deque,而Deque接口定义了在双端队列原创 2021-07-24 16:57:23 · 195 阅读 · 0 评论 -
Java集合List之源码Vector
Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:Vector 是同步访问的。Vector中的操作是线程安全的默认2倍扩容,可自定义,如下图所示源码流程图public static void main(String[] args) { List list = new Vector<>(); List list1 = new Vector<>(10,10); list.add(1); list.remov原创 2021-07-22 00:49:37 · 234 阅读 · 0 评论 -
并发编程(五)AbstractQueuedSynchronizer(AQS)-CountDownLatch、CyclicBarrier
CountDownLatchCountDownLatch是什么?CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。CountDownLatch如何工作?CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。Co原创 2021-07-22 00:33:39 · 129 阅读 · 1 评论 -
并发编程(四)AbstractQueuedSynchronizer(AQS)-Semaphre(限流)源码分析跟踪
Semaphore 通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。共享锁默认创建非公平锁Semaphore保证的是资源的互斥而不是资源的同步,在同一时刻是无法保证同步的,但是却可以保证资源的互斥。使用场景经常用于限制获取某种资源的线程数量(限流)emaphore常用方法说明acquire()获取一个令牌,在获取到令牌、或者被其他线程调用中断之前线程一直处于阻塞状态。acquire(int permits)获取一个令原创 2021-07-21 22:22:58 · 154 阅读 · 0 评论 -
并发编程(三)AbstractQueuedSynchronizer(AQS)-ReentrantLock可重入、独占锁
并发之父 Doug LeaAbstractQueuedSynchronizerJava并发编程核心在于java.concurrent.util(juc)包juc当中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这个行为的抽象就是基于AbstractQueuedSynchronizer简称AQS,AQS定义了一套多线程访问共享资源的同步器框架,是一个依赖状态(state)的同步器(state:记录当前是否枷锁,枷锁的次数等等,引入可重入的功能 )等待队列原创 2021-07-16 01:40:06 · 176 阅读 · 2 评论 -
并发编程(二)synchronized锁
前言多线程编程中,有可能会出现多个线程同时访问同一个共享、可变资源的情况, 这个资源称之其为临界资源;这种资源可能是:对象、变量、文件等。共享:资源可以由多个线程同时访问可变:资源可以在其生命周期内被修改由于线程执行的过程是不可控的,所以需要采用同步机制来协同对对象可变状态的访问所有的并发模式在解决线程安全问题时,采用的方案都是序列化(有序)访问临界资源。即在同一时刻,只能有一个线程访问临界资源,也称作同步互斥访问。当多个线程执行一个方法时,该方法内部的局部变量并不是临界资源,因为这些局部变原创 2021-07-15 01:21:21 · 259 阅读 · 1 评论 -
设计模式-抽象工厂模式
/** * 抽象工厂模式 * 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 * RefrigeratorUtils 依赖 Open、Put * * 主要解决:主要解决接口选择的问题。 * * 何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。 * * 如何解决:在一个产品族里面,定义多个产品。 * * 优点:可以确信你从工厂得到的产品彼此是兼容的 * 可以避免具体产品和客户端代码之间的紧密耦合 * 符合单一职责原创 2021-06-08 16:37:22 · 97 阅读 · 5 评论 -
设计模式-工厂方法模式
工厂模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。介绍意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。主要解决:主要解决接口选择的问题。何时使用:我们明确地计划不同条件下创建不同实例时。如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。关键代码:创建过程在其子类执行。应用实例:您需要一辆汽车,可原创 2021-06-03 21:39:35 · 81 阅读 · 0 评论 -
设计模式-单例模式(懒汉、饿汉、枚举)
单例模式单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。注意:单例类只能有一个实例。单例类必须自己创建自己的唯一实例。单例类必须给所有其他对象提供这一实例。介绍意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。主原创 2021-06-02 17:44:49 · 342 阅读 · 1 评论 -
并发编程(四)线程的风险
1.活跃性问题死锁:指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进(五个哲学家吃饭,每个人一只筷子,谁都不肯舍弃自己的筷子,最终饿死的事情,其实就是一个死锁的问题)饥饿:线程因无法访问所需资源而无法执行下去的情况(例如购买车票,买完车票占着窗口不走,导致后面的人无法购票)。活锁:活锁恰恰与死锁相反,死锁是大家都拿不到资源都占用着对方的资源,而活锁是拿到资源却又相互释放不执行。饥饿情景高优先级吞噬所有低优先级的CPU时间片线程原创 2021-04-28 22:44:35 · 112 阅读 · 0 评论 -
并发编程(三)CPU缓存模型、Java内存模型及关键字volatile的使用
1、CPU缓存模型CPU缓存是位于CPU与内存之间的临时数据交换器,它的容量比内存小的多但是交换速度却比内存要快得多。CPU缓存一般直接跟CPU芯片集成或位于主板总线互连的独立芯片上。为了简化与内存之间的通信,高速缓存控制器是针对数据块,而不是字节进行操作的。高速缓存其实就是一组称之为缓存行(Cache Line)的固定大小的数据块组成的,典型的一行是64字节。CPU缓存通常分成了三个级别:L1,L2,L3。级别越小越接近CPU,所以速度也更快,同时也代表着容量越小。如果是windows系统可以查看任原创 2021-04-28 22:43:57 · 246 阅读 · 0 评论 -
并发编程(二)线程的多种创建方式
1.继承thread方式实现线程public class Demo1 extends Thread{ public Demo1(String name){ super(name); } @Override public void run(){ // 测试当前线程是否中断 while (!interrupted()){ System.out.println(getName()+"thread----i原创 2021-04-26 21:52:44 · 107 阅读 · 0 评论 -
并发编程(一)进程、线程、并发、并行
1、进程程序是由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存。在指令运行过程中还需要用到磁盘,网络等设备。进程就是用来加载指令,管理内存,管理IO的。当一个程序被运行,从磁盘加载这个程序的代码至内存中,这时就开启了一个进程进程可以视为一个程序的实例,但部分程序可以运行多个实例(例如浏览器,记事本等),也有的程序只能启动一个实例进程(Sublime、360等)2、线程一个进程之内可以分为一到多个线程(如:一个java进程,会有多个线程)一个线程就是原创 2021-04-23 00:08:15 · 154 阅读 · 0 评论 -
利用aop自定义注解
自定义注解记录log// (元注解)表示我们的注解可以用在那些地方@Target(ElementType.METHOD)// (元注解)表示我们的注解在什么地方有效:source(源码)< class(编译后)< runtime(运行时)@Retention(RetentionPolicy.RUNTIME)// (元注解)表示是否将我们的注解生成在javadoc中@Documented// (元注解)子类可以继承父类的注解@Inheritedpublic @interface原创 2021-04-21 21:23:43 · 239 阅读 · 0 评论 -
Java什么是反射、利用反射获取配置文件中信息
1、前言一般情况下我们在开发中都是根据需求来编写代码,比如我有一个user表,user表有3个字段,id,name,age。对user做CRUD。创建一个实体类,User,定义成员变量,构造方法,成员方法等操作。public class user{ private Integer id; private String name; private Integer age; private user(){} private user(Intege原创 2021-04-20 21:34:18 · 438 阅读 · 2 评论 -
什么是WebSocket、WebSocket的应用场景
什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议2008年诞生于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。WebSocket协议与http协议对原创 2021-01-19 22:57:05 · 506 阅读 · 0 评论 -
StringBoot启动项目回调方法
package com.generator;import org.springframework.boot.ApplicationArguments;import org.springframework.boot.ApplicationRunner;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.SpringApplication;import org.springframewor原创 2021-01-17 21:56:46 · 107 阅读 · 0 评论 -
Java 两个集合的差集、交集、并集、去重、数组转list、list转数组
/** * List差集 返回的是 frontList 相对于 afterList 差集 * 如:frontList:1,2,3 * afterList 3,4,5 * 结果:1,2 * 如:frontList:3,4,5 * afterList 1,2,3 * 结果:4,5 * @param frontList * @param afterList * @retur...原创 2020-11-20 14:39:05 · 233 阅读 · 0 评论 -
直接用tomcat启动项目
找到tomcat的安装目录例如我的安装目录:E:\install\apache-tomcat-7.0.59 找到webapps文件夹,将项目放入其中启动tomcat启动方式 : E:\install\apache-tomcat-7.0.59\bin文件中 startup.bat 启动原创 2017-02-08 13:48:48 · 2253 阅读 · 1 评论 -
SpringMVC (SSM) 配置Kaptcha验证码
模型原创 2017-02-08 12:59:29 · 4471 阅读 · 6 评论 -
SVN查看提交历史
桌面或者某地右键选择: 如下图选择Repo-browser 如下图样式(我划掉了勿怪) 输入svn账号密码略过了右键项目选择Show log现在显示的内容 既是每次提交的代码的历史信息原创 2017-02-08 10:47:01 · 17343 阅读 · 0 评论 -
Eclipse jdk1.7 Maven 编译错误 Dynamic Web Module 3.0 requires Java 1.6 or newer 解决方案
Eclipse Maven 开发一个 jee 项目时,编译时遇到以下错误:DescriptionResource PathLocation TypeDynamic Web Module 3.0 requires Java 1.6 or newer. bdp line 1 Maven Java EE Configuration ProblemDescription R转载 2016-09-18 08:47:43 · 1085 阅读 · 0 评论 -
光标悬停显示文字和执行方法
鼠标停留显示文字title的值为停留显示内容鼠标停留执行方法: title="">hello' + data[i].vendorName + '';function over(tel){};function out(){};原创 2016-09-12 15:06:58 · 1057 阅读 · 0 评论 -
String与StringBuffer的区别
简单地说,就是一个变量和常量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。StringBuffer的内部实现方式和String不同,StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringB转载 2016-09-12 14:56:44 · 293 阅读 · 0 评论 -
Java中equals和==的区别
java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==),比较的是他们的值。 2.复合数据类型(类) 当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结原创 2016-09-12 14:53:07 · 434 阅读 · 0 评论 -
使用JDBC数据迁移把Mysql数据到另一个库中
数据迁移简介:整体思路链接2个需要迁移的数据库 根据sql 进行查询 判断什么样的数据需要迁移,什么样的数据需要过滤掉,数据重复或者出错的情况输出到某个文件中如果数据可以整体迁移而且不出格式差异的情况也可以直接导出sql文件进行迁移 此文仅供参考数据库迁移方式: 1.JDBC 迁移 2.从一个库导出sql文件到另一个库中执行sql文件原创 2017-04-07 14:11:17 · 2507 阅读 · 2 评论 -
http get 请求地址传中文或值带特殊符号解决方法 URLEncoder.encode(str,"编码") new URLDecoder().decode(str,"编码")
get 请求调用原本 对象的值为json类型 {}导致请求报错 URLEncoder.encode(str,"编码")JSONObject jsonObject = JSONObject.fromObject(mapparams);URLEncoder.encode(jsonObject.toString(),"UTF-8");原创 2017-11-08 15:23:47 · 1179 阅读 · 0 评论 -
StringUtils中 isNotEmpty 和isNotBlank的区别
isNotEmpty :判断某字符串是否非空StringUtils.isNotEmpty(null) = falseStringUtils.isNotEmpty("") = falseStringUtils.isNotEmpty(" ") = trueStringUtils.isNotEmpty("bob") = trueisNotBlank:判断某字符串是否不为空且长度不为0且不由空白符(whi原创 2016-09-12 14:58:56 · 1124 阅读 · 0 评论 -
Http的GET请求与POST请求调用接口
GET请求public static String doGet(Map mapparams) { // 返回对象 String result = ""; try { // 传参 JSONObject jsonObject = JSONObject.fromObject(mapp原创 2017-11-17 13:19:18 · 1827 阅读 · 0 评论 -
Java获取项目相关路径
String url66 = getRequest().getScheme()+"://"+ getRequest().getServerName()+getRequest().getRequestURI()+"?"+getRequest().getQueryString(); System.out.println("获取全路径(协议类型://域名/项目名/命名空间/action名原创 2018-01-29 15:44:43 · 364 阅读 · 0 评论