
java
文章平均质量分 74
分享一些实用技巧,学习总结一些知识。
cpown
干就完了
展开
-
JVM 常用参数
JVM 常用参数-Xmx/-Xms最大和初始堆大小。最大默认为物理内存的1/4,初始默认为物理内存的1/64。-Xss等价于-XX:ThresholdStackSize。用于设置单个栈的大小,系统默认值是0,不代表栈大小为0。而是根据操作系统的不同,有不同的值。比如64位的Linux系统是1024K,而Windows系统依赖于虚拟内存。-Xmn新生代大小,一般不调。-XX:MetaspaceSize设置元空间大小。-XX:+PrintGCDetails输出GC收集信息,包含GC和Full原创 2020-10-24 20:39:51 · 345 阅读 · 0 评论 -
阻塞队列 BlockingQueue 实现生产者消费者模式线程通信
概念:当阻塞队列为空时,获取(take)操作是阻塞的;当阻塞队列为满时,添加(put)操作是阻塞的。好处:阻塞队列不用手动控制什么时候该被阻塞,什么时候该被唤醒,简化了操作。体系:Collection→Queue→BlockingQueue→七个阻塞队列实现类。类名作用ArrayBlockingQueue由数组构成的有界阻塞队列LinkedBlockingQueue由链表构成的有界阻塞队列PriorityBlockingQueue支持优先级排序的无界阻塞队列原创 2020-10-13 22:09:36 · 566 阅读 · 1 评论 -
Synchronized和Lock的区别
synchronized关键字和java.util.concurrent.locks.Lock都能加锁,两者有什么区别呢?原始构成:sync是JVM层面的,底层通过monitorenter和monitorexit来实现的。Lock是JDK API层面的。(sync一个enter会有两个exit,一个是正常退出,一个是异常退出)使用方法:sync不需要手动释放锁,而Lock需要手动释放。是否可中断:sync不可中断,除非抛出异常或者正常运行完成。Lock是可中断的,通过调用interrupt()方法。原创 2020-10-13 21:30:48 · 243 阅读 · 0 评论 -
ReentrantReadWriteLock 实现手写缓存,并发读取、阻塞添加
前言我们在大多数业务中遇到并发问题,最先想到的是,Synchorized,以及 ReentrantLock,但是这两种锁是重量级的,也是阻塞的锁,一个线程获取了锁,其他线程必须阻塞,并发性能大大降低。今天我们来介绍一下java.util.concurrent.locks包下面的另一把锁:ReadWriteLock 读写锁,顾名思义,就是可以区分读还是写操作,展现不同的锁类型,做到并发读取,阻塞写入,使性能大大提升。案例本文我们使用一个简单的手写缓存Demo来展示一下锁的特性以及功能。package原创 2020-10-08 17:50:30 · 328 阅读 · 0 评论 -
基于 Redis 实现分布式锁
问题背景实际开发场景中,可能需要处理并发线程互斥地访问某个共享资源。 Java中通常用synchronized、Lockd来加锁,避免多线程中由于竞争导致的数据不一致问题。问题是Java中的锁,只在同一JVM环境下才生效。分布式系统中,应用部署在多台服务器。这时候需要使用分布式锁,利用一个第三方节点来获取/释放锁。分布式锁实现方式有数据库、redis、zookeeper等,基本原理是一样的:标识锁状态+锁的唯一持有者。 这里只介绍单节点下redis实现分布式锁要求互斥性(加锁):任意时刻只原创 2020-09-30 16:20:40 · 327 阅读 · 0 评论 -
使用CloseableHttpClient发送 Put请求
首先创建Http连接池工具类:PoolingHttpClientConnectionUtils:package com.epean.ops.utils;import java.io.IOException;import java.net.BindException;import java.security.GeneralSecurityException;import java.security.cert.CertificateException;import java.security.ce原创 2020-09-24 17:13:32 · 1569 阅读 · 0 评论 -
java 从字符串里面提取时间
今天接到一个需求,需要从一段带有时间串的字符串里面提取出时间保存。"PDFS(iZh9k5gurgwcwpZ) 2020-01-01 21:27:36.560 >订单编号:1112233 提交订单成功! 跟踪号:待取跟踪号 内部单号:2342244"需要从上面数据中心提取出 2020-01-01 21:27:36要怎么操作呢?我们可以使用正则表达式,对时间串进行提取,并处理,代码如下:package com.epean.trade.framework.util;import原创 2020-08-21 10:20:34 · 5989 阅读 · 1 评论 -
Comparable 和 Comparator 的区别和使用
在我们实际开发过程中,经常会遇到各种各样的排序,我们都知道,基本数据类型排序就是按照数值大小排序。如果我们需要按照对象的某一个属性进行对象的比较排序,比如,按照商品的价格对商品进行排序,或者按照学生的升高对学生进行排序,这就涉及到对象间的排序。应该怎么做呢?一、自然排序:java.lang.Comparablejava.lang包下的Comparable接口会强行对他的实现类进行排序,这种排序规则称之为类的自然排序。例如String类,以及基本数据类型的包装类如Integer,Double等都实现了原创 2020-08-14 22:19:01 · 316 阅读 · 0 评论 -
自从使用了Semaphore,再也不用担心接口并发频率限制了
今天在写代码时遇到一个问题,在对接shopify电商平台api接口时,使用多线程并发处理数据返回了一个报错:Exceeded 2 calls per second for api client. Reduce request rates to resume uninterrupted service.平台接口有频率限制一秒钟只能够请求两次,多线程并发处理,导致大量数据处理失败,咋整?按照我们以前的思维,这里肯定不适合使用多线程,乖乖换回单线程处理,并且每个请求睡眠0.5s。但是作为一个多年经验的原创 2020-07-21 14:50:07 · 908 阅读 · 0 评论 -
java自定义注解实现校验对象属性是否为空
前面学习了如何自定义一个注解:java如何优雅的自定义一个注解下面来实战演示一下如何使用自定义注解做一些实际的功能。比如校验对象属性是否为空。一、自定义一个NotNull注解我们自定义一个NotNull注解,里面有一个参数message 默认为“”;/** * 自定义注解 * 判断屬性不为空注解 */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface NotNull { /*原创 2020-07-03 12:15:44 · 7034 阅读 · 0 评论 -
java8新特性之新的时间和日期
我们一直以来在写代码使用的时间无外乎两种,Date和Calender。但是传统的时间 API 存在线程安全的问题,在多线程开发中必须要上锁,所以 java8 现在为我们提供了一套全新的时间日期 API ,今天进来学习一下java8 的时间日期 API。一、LocalDate、LocalTime、LocalDateTimeLocalDate、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用 ISO-8601 (ISO-8601 日历系统是国际化组织制定的现代化公民的日期原创 2020-07-01 22:41:40 · 2950 阅读 · 0 评论 -
java8新特性之方法引用与构造器引用
本文用使用大量内置函数式接口,可参考上篇文章:java8新特性之函数式接口使用1.使用场景当要传递给Lambda体的操作,已经存在实现的方法了,就可以使用方法引用。(抽象方法的参数列表 必须与方法引用方法的参数列表保持一致),可以理解为lambda的另一种表现形式。2. 语法使用操作符【::】将方法名和对象或类的名字分开。三种主要使用情况:1)对象::实例方法名注:消费型接口,参数类型为String,返回值为void,System.out.println(x)的参数类型也是String,返回值原创 2020-06-30 22:21:53 · 296 阅读 · 0 评论 -
java8新特性之函数式接口使用
我们都知道java8的主要新特性是,stream流以及lambda表达式。java8内置了很多函数式接口,但是最基本的四大函数式接口,已经足以应付绝大多数场景。今天我们讲解一下,使用lambda表达式实现java8四大内置函数式接口。一、消费型接口 Cousumer< T>Cousumer类型接口没有返回值,参数为T,执行格式为accept(T t): public static void main(String[] args) { //使用lambda表达式调用ha原创 2020-06-29 21:35:48 · 500 阅读 · 0 评论 -
java使用wait()和notify()实现线程通信
我们都知道线程睡眠的方法有两种,一中是Thread.sleep(),一中是Object实例化对象.wait()。今天我们着重说一下wait()的作用,我们都知道wait()如果没有参数的话线程会一直处于睡眠状态,除非主动唤醒,主动唤醒的方式有两种:notify()或者notifyAll(); 现在我们来使用wait()以及notifyAll()来实现线程通信。首先我们假定一个场景:有四个角色,分别是厨房,食客,鸡,以及存放鸡的器皿。厨房:负责将鸡烹饪好。食客:负责吃鸡。器皿:盛放烹饪好的鸡。鸡原创 2020-06-29 15:30:22 · 382 阅读 · 0 评论 -
【详细】java如何优雅的自定义一个注解?
说到注解,我们一定都不陌生,在我们编码过程中可以说是无处不在,非常的常见。比如:@Override,@Deprecated,@Controller等等。那么我们今天来说一下如何自定义一个注解。一、注解的基本结构我们在代码里面点开一个注解看一下:package java.lang;import java.lang.annotation.*;/** * Indicates that a method declaration is intended to override a * method原创 2020-06-17 21:19:22 · 4492 阅读 · 0 评论 -
java进阶之反射
我们都知道java是一门静态语言,通过class文件在虚拟机里面运行。但java里面有一个反射机制,可以使java语言变成一门“准动态语言”。使用反射机制可以使java语言变得更加灵活。今天我们说一下java的反射机制。一、什么是反射(Reflection)反射(Reflection)是java被视为动态语言的关键,反射机制允许程序在执行期间,借助于Reflection Api 获取类的内部信息,并能够直接操作类的内部属性和方法。...原创 2020-06-16 22:06:01 · 588 阅读 · 0 评论 -
jvm类的初始化加载过程
本篇文章说一下java虚拟机类的加载过程。手先我们看一下下面的代码:package mytest;public class Test { public static void main(String[] args) { A a = new A(); System.out.println(A.m); }}class A { public static int m = 300; static { System.o原创 2020-06-15 19:39:33 · 366 阅读 · 0 评论 -
volatile关键字有什么用?
说道volatile关键字,大家都不陌生,它可以使一个变量在多个线程中可见;但是volatile并不能保证多个线程共同修改一个变量时所带来不一致的问题,即volatile只能保证可见性,不能保证原子性。如果既要保证可见性又要保证原子性可以使用synchronized。线程1,线程2都用到一个变量,java默认是线程1中保留一份copy,这样如果线程2修改了该变量,则线程1未必知道。要了解可见性,我们得先来了解一下 Java 内存模型。Java 内存模型(Java Memory Model,简称原创 2020-06-05 19:04:27 · 627 阅读 · 0 评论 -
如何正确的使用synchronized关键字
参考二哥:https://blog.youkuaiyun.com/qing_gee/article/details/106032117一、为什么使用synchronized在多线程并发修改共享数据时无法保证线程安全。synchronized关键字可以保证在某一时刻只有一个线程可以访问某个方法或者代码块,只有当前线程执行完成其他线程才能够重新拿到执行权力。下面我们来演示一下如果不是用synchronized关键字的情况下,使用多线程操作会出现什么情况。首先我们创建一个类SynchronizedMethod,里面只原创 2020-06-04 14:47:10 · 819 阅读 · 0 评论 -
maven插件自动生成pojo以及mapper映射文件
写代码的时候新建了一张表,是不是觉得创建实体类以及映射文件贼鸡儿烦?问题不大:有一个东西叫做Mybatis-generator这玩意可以根据我们已经设计好的数据库表帮助我们自动生成实体类(pojo)、接口(dao)、映射文件(mapper),这样就可以避免每次使用表的时候手动创建一些类和映射文件,节约了大量的时间。简单粗暴易上手,话不多少直接开搞。首先创建一个maven项目,这一步我就不多说了,IDEA一站式操作,没啥好说的。创建完项目,我们先创建一张表格备用sys_user 字段如下:下原创 2020-05-29 16:29:40 · 1300 阅读 · 0 评论 -
Java线程池如何优雅地等待所有任务执行完
随着项目的体量越来越大,对代码的执行效率要求越来越高,在实际应用过程中我们会经常使用线程池。那么如果线程池嵌入在业务代码中,如何正确的等待线程池执行完,在执行后续操作呢?或者想要获取执行结果有应该怎么处理呢?下面走一下场景:package com.example.demo1.entity;/** * create by c-pown on 2019-12-06 */public class Student { private String name; private Int原创 2020-05-25 17:50:29 · 22534 阅读 · 1 评论 -
随机获取List中的数据,顺序随机,大小自选
上一篇我们说了,等额切割List等额拆分List这次我们说一下如何随机获取一个list中数据,大小可变,位置随机。上代码:package com.example.demo1.util;import java.util.*; /** * @desc 随机获取List数据 * @date 2020-05-25 */public class SplitArrayUtils { /** * 随机获取长度为size的list<br>原创 2020-05-25 11:23:24 · 1657 阅读 · 1 评论 -
等额拆分List
在项目进行的过程中,难免会出现插入,或者修改大批量数据。我们都知道,大批量的操作数据库数据会对数据库资源造成巨大损耗,查询sql卡顿,直接影响整个项目的数据库性能。那要怎么办呢?我们可以对将要操作的数据进行等额的拆分,然后分批次进行数据库修改。下面直接上代码:package com.epean.trade.framework.util;import java.util.*; /** * @desc 等额拆分数组 * @author chenp * @date 2020-原创 2020-05-25 11:05:07 · 681 阅读 · 0 评论