
java
文章平均质量分 77
Mutou_ren
这个作者很懒,什么都没留下…
展开
-
synchronized和lock保证的可见性
synchronized在进入时要读取主存,退出时刷新主存。但不会禁止重排序,只会保证锁内和锁外的排序不会乱,因此只能保证刚进入时数据是最新的原创 2020-07-24 09:45:33 · 1650 阅读 · 0 评论 -
volatile修饰List能否保证内部元素的可见性?
实验一:ArrayList多线程下的可见性代码 private static List<Integer> list; static { list = new ArrayList<Integer>(20); list.add(0); } public static void main(String[] args) throws InterruptedException { CountDownLatch l原创 2020-07-23 10:30:51 · 3640 阅读 · 2 评论 -
synchronized加锁对象有什么要求?
不同线程通过synchronized锁对象,要想让锁达到效果,必须保证多个线程锁住的是同一个对象。不要锁包装类:自动装箱使用的是valueOf方法,若没有缓存则会new一个包装对象,所以拿到的是不同对象,无法实现锁。不要锁参数对象,SpringMVC在参数绑定时生成的参数对象是独立的锁String字段时,要使用String.intern()返回的。该方法返回的是指向常量池的对象指针,可以保证是同一个。对于StringString s1 = new String("jwb")//堆String原创 2020-07-24 09:47:55 · 1229 阅读 · 0 评论 -
图解JDK7中的HashMap闭环和丢失问题
关于HashMap的线程安全问题,网上资料很多。对于1.7版本的闭环问题,看了很多网上的资料一直搞不懂,今天又琢磨了一下,终于明白了,用自己看得懂的方式记录下。首先说下闭环产生的原因:1.7的HashMap在扩容复制时,采用的是头插入法,这会导致原数组中的链表反转,即将原来的正向,复制成反向链表。而在多线程环境下,可能存在其他线程完成了扩容复制操作,完成了后的数组链表变成了原来的反向链表。由于可见性的保证,当前线程继续复制时,复制的时其他线程已经完成了的反向链表,但当前线程又会将其反转,导致又变成了正原创 2020-05-19 21:33:56 · 998 阅读 · 0 评论 -
Cglib动态代理的底层原理
使用老规矩,先回忆一下怎么使用cglib的动态代理写一个方法拦截器作为回调创建Enhancer并设置父类和回调使用Enhancer创建代理类public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method ...原创 2020-03-04 22:22:52 · 702 阅读 · 0 评论 -
基于Javassist实现JDK的动态代理Proxy
使用首先复习一下怎么使用动态代理定义一个用户接口实现一个用户接口的实现类实现一个InvocationHandler使用Proxy.newProxyInstance创建一个代理即可使用public interface SayHelloInterface { void addMessage(String msg,String from,String to); Strin...原创 2020-03-04 21:00:42 · 535 阅读 · 0 评论 -
Java中的对象拷贝
我们在开发中有时候会经常需要进行对象拷贝的情况,举个例子 public static void main(String[] args) { m1(o); m2(o); } public static void m1(Object o){ //会对o进行修改 } public static void m2(Object o){...原创 2020-02-06 13:24:45 · 292 阅读 · 0 评论 -
Java包装类中的缓存
缓存包装类为了提高性能,会将最常用范围的基本数值对应的包装类进行缓存,通常使用cache内部类的static静态代码块进行缓存填充操作,valueOf()中存在缓存读取操作。我们通常定义包装类型时Integer a = 1,其默认就是使用的valueOf()方法,可自行通过javap进行反编译查看。Integer a = 1;Long b = 2l;Character c = 'a';...原创 2020-02-06 12:37:13 · 260 阅读 · 0 评论 -
HashMap的初始容量设置为多少合适?
我们知道对于List、Map这种底层是基于数组的动态容器,在扩容时会进行数组复制,因此为了避免这种额外开销,应该尽量在创建时指定大小。对于没有负载因子的如List,其扩容策略为满了后下次插入进行扩容,因此初始化大小为需要大小即可对于存在负载因子的HashMap、HashSet等,其扩容策略为本次插入后并判断自增后是否超过了阈值(容量*负载因子),如果超过了则进行扩容。因此初始化时指定的容量应为...原创 2020-02-03 17:37:31 · 4285 阅读 · 0 评论 -
CompletableFuture的用法及简要原理
//自定义线程池private static ThreadPoolExecutor executor = new ThreadPoolExecutor(8,16,20, TimeUnit.SECONDS,new LinkedBlockingDeque<>(20), Executors.defaultThreadFactory(), (r, executor1) -> new T...原创 2020-01-12 17:15:10 · 1143 阅读 · 0 评论 -
AQS的doAcquire和doRelease
上篇博客讲了tryAcquire和tryRelease,这篇来看看AQS自身实现的doAcquire和doReleaseacquire独占锁AQS自身没有提供对doAcquireInterruptibly和doAcquireNanos的调用,交由子类使用,这俩都将同步队列节点入队操作放在了自己的方法内,而AQS自身对acquireQueued的实现acquire将这个操作从do方法中移了出来...原创 2020-01-07 22:45:21 · 328 阅读 · 0 评论 -
AQS的非公平锁与同步队列的FIFO冲突吗?
公平锁与非公平锁的含义都很明白,公平锁必须排队获取锁,锁的获取顺序完全根据排队顺序而来,而非公平就是谁抢到是谁的。我们都知道AQS中的锁获取,如果首次获取失败会进入到内部的同步队列中阻塞等待,只有前面的节点唤醒当前节点才能去尝试获取锁从我之前的博客内容可知,锁获取的核心,实际上是在try方法中定义的,在节点从阻塞中醒来时,都会用try方法来获取锁,而公平与否在try方法中体现,即在公平锁中,t...原创 2020-01-07 22:44:49 · 1681 阅读 · 19 评论 -
AQS子类的tryAcquire和tryRelease的实现
思想AQS通过一个private volatile int state;来表示锁的状态,当state=0时代表无锁,>0代表有锁,>1代表重入次数AQS从AOS继承了private transient Thread exclusiveOwnerThread;用来记录当前持有独占锁的线程暴露方法// 尝试获取 独占锁protected boolean tryAcquire(in...原创 2020-01-07 19:50:43 · 1787 阅读 · 0 评论 -
Semaphore实现原理
示例代码public class TestSemaphore { public static Semaphore semaphore=new Semaphore(2); public static void main(String[] args) { System.out.println("main start"); for (int i =0...原创 2020-01-04 14:42:16 · 208 阅读 · 0 评论 -
CyclicBarrier的实现原理
示例代码public class TestCyclicBarrier { public static CyclicBarrier barrier = new CyclicBarrier(4,()-> { System.out.println(Thread.currentThread().getName()+"dododo"); try { ...原创 2020-01-04 14:00:31 · 189 阅读 · 0 评论 -
基于AQS分析CountDownLatch的原理
示例代码先贴一段示例代码public class TestCountDownLatch { public static CountDownLatch countDownLatch = new CountDownLatch(3); public static void main(String[] args) throws InterruptedException { ...原创 2020-01-03 21:54:08 · 257 阅读 · 0 评论 -
为什么JVM分代机制中的新生代要分两个survivor
我们知道在基于分代机制的JVM内存模型中,新生代被分成了eden、from、to三个区,占比8:1:1,from和to完全等价可以互换,平时使用eden+from,GC时将存活对象复制到to区,然后清空eden+from,from与to身份互换。为什么要分from+to两个区?只分一个比如只分为eden+from不是也可以吗?GC时将存活对象复制到from然后清空eden不就可以了吗?传统复制...原创 2019-12-30 21:54:16 · 884 阅读 · 0 评论 -
synchronize和Lock区别
以前一直说synchronize是一种重量级锁,因为以前synchronize是没有锁升级这个机制的,多个线程竞争锁时没有拿到锁的会直接进入阻塞状态,而后来引入了锁升级后,synchronize便没那么重了,具体可参加我的另一篇文章synchronizesynchronize的加锁是在对象头进行操作的,而Lock是基于AQS中的state进行的,每次进入锁就会使state+1,而在基于AQS的L...原创 2019-12-29 11:54:09 · 220 阅读 · 0 评论 -
基于AQS分析Condition
对于Object的wait和notify方法我们已经很熟悉了,同时也知道与之相似的Condition接口,具体用法这里不讲,我们基于上一篇AQS的介绍来讲讲Condition的实现原理等待队列Condition的实现类ConditionObject是AQS的内部类,其实现是需要获取Lock相关的锁,且实现方式也与AQS很相似我们知道在AQS中存在一个同步队列,当线程没有获取到锁时,同步器会将...原创 2019-12-28 21:26:15 · 372 阅读 · 0 评论 -
0代码讲解Java中AQS的实现原理
我们知道Java中的锁有Synchronize和Lock,而Lock是基于队列同步器AQS(AbstractQueuedSynchronizer)实现的,今天来分析一下到底什么是AQS这里不贴代码,只讲思想原理,代码其实很简单,原理理解了,翻翻源码就知道了什么是锁?首先明确一下什么是锁,所谓锁,无非就是一个独一份的共享资源,多个线程去抢这个资源,谁拿到了这个共享资源谁就持有了锁。表现在代码...原创 2019-12-28 11:32:43 · 301 阅读 · 2 评论 -
Java中的偏向锁、轻量级锁、重量级锁以及锁升级
什么是锁?Java中的锁的状态有四种:无锁、偏向锁、轻量级锁、重量级锁,状态会随竞争状态改变,低等级的锁可以升级为高等级的锁,即锁升级;但反之不行,没有锁降级。要理解锁升级,首先要了解一些基本概念:加锁行为到底锁的是什么?加锁记录存在哪里?我们以Java最常见的synchronized为例首先要理解,锁是一种排他状态,是一种竞争性的共享资源,谁拿到了这个共享资源,谁就持有了锁。如基于...原创 2019-12-14 15:47:51 · 341 阅读 · 0 评论 -
ThreadLocal的底层实现
我们都知道,ThreadLocal提供了一种将资源绑定到当前线程的手段,实现资源在线程之间的隔离。通过set和get方法能够进行资源的存取操作。从它的方法来看,仿佛ThreadLocal就是个容器,为我们保存资源,实际上是这样的吗?它到底是怎么做到线程隔离的?问题描述定义一个ThreadLocal对象local,线程t1和t2均会使用local.set放置资源,t1,t2在通过get获取时又...原创 2019-11-14 16:26:17 · 286 阅读 · 0 评论 -
事物的传播行为以及应用场景
事物的传播行为有七种,不仅要知道这七种分别是什么意思,还要知道分别适合哪种场景使用。在service1中调用了service2方法,则service2可以定义以下不同事物传播行为PROPAGATION_REQUIRED解释:如果当前存在事物,则加入该事物;如果不存在事物,则创建一个新的事物。该行为一般被设置为默认场景:service2要至少保证在一个事物中运行PROPAGATION_S...原创 2019-11-13 15:39:55 · 2781 阅读 · 0 评论 -
自定义TTLHashMap
使用DelayQueue保存Key值,用redis的渐进式哈希的思想在每次操作时进行过期清理(小步清理目前有bug后续完善)public interface TtlMap extends Map { Object put(Object key, Object value,long ttl);}public class DelayedKey implements Delayed {...原创 2019-10-24 16:23:37 · 951 阅读 · 0 评论 -
WeakHashMap
http://www.importnew.com/23182.html转载 2018-10-27 10:26:53 · 175 阅读 · 0 评论 -
try-with-recourse
https://www.cnblogs.com/itZhy/p/7636615.html转载 2018-09-23 19:39:58 · 228 阅读 · 0 评论 -
高并发项目总结
功能实现两次MD5加密密码第一次MD5Http是明文传输,为了不泄露密码,用户在前端表单输入时,在前端对密钥做第一次MD5处理,发送给后端。第二次MD5后端收到密码后做第二次MD5处理,并存入数据库中。这是防止数据库泄露根据彩虹表反向推到出用户密钥。为了增强密码安全,增加随机盐值混淆密码JSR303参数校验对VO层对象的属性设定限制,如格式、非空等,无需在每个方法里重复判断。...原创 2019-01-27 16:14:13 · 1398 阅读 · 0 评论 -
BLOCKED,WAITING,TIMED_WAITING有什么区别?-用生活的例子解释
https://segmentfault.com/a/1190000010973341?utm_source=tag-newest转载 2018-12-13 10:09:25 · 985 阅读 · 1 评论 -
java基础——重写、隐藏、重载
方法签名:方法名+参数列表(参数类型、个数、顺序)重写:子类重写父类方法,仅限于实例方法。成员变量和静态方法不能被重写,只能被隐藏。重写原则:1.方法名相同,参数类型相同。2.子类返回类型小于等于父类返回类型。3.子类异常小于等于父类异常。4.子类访问权限大于等于父类访问权限。重写方法可以改变其他方法修饰符如final,synchronize,native等。不管被...原创 2018-10-11 20:17:44 · 202 阅读 · 0 评论 -
hashmap底层原理
https://blog.youkuaiyun.com/a2524289/article/details/78888480转载 2018-09-25 21:23:45 · 151 阅读 · 0 评论 -
Optional类---解决npe问题
https://www.cnblogs.com/zhangboyu/p/7580262.htmlhttp://www.runoob.com/java/java8-optional-class.html转载 2018-09-23 20:01:34 · 484 阅读 · 0 评论 -
finally中的return
在try-catch-finally的finally中return时,将不会执行try中的return,即finally中的代码是先于try中的return语句执行的,会造成覆盖。其他详细 int x; try { x=1; return x; }catch (ArithmeticException...转载 2018-09-23 19:45:40 · 730 阅读 · 0 评论 -
双重检查锁
https://www.cnblogs.com/xz816111/p/8470048.html转载 2018-09-23 18:58:04 · 318 阅读 · 0 评论 -
阿里巴巴开发手册——集合
阿里开发手册笔记:集合1.ArrayList的sublist(form,to)返回父list的一个视图,包含from不包含to,它是ArrayList的内部类,无法强制转换成ArrayList。父子做出的非结构性更改(不含大小)会互相影响到彼此当子list更改大小时,父list也会受到影响。父list修改大小时,子list失效,此时对子list的遍历、增加、删除会抛出Concu...原创 2018-09-23 17:57:18 · 2089 阅读 · 0 评论 -
设计模式——单例模式
单例模式保证了某个对象只有一个实例,单例可以节省开销,同时能够避免多个实例引起的多线程问题。单例分为饿汉模式和懒汉模式。饿汉模式将类的构造器私有化,防止外部实例化对象 在类内部自身实例化一个对象,唯一且私有 提供一个公共静态的获取实例方法,用来获取这个唯一的实例public class Single{ private Single(){ }...原创 2018-09-06 20:21:45 · 142 阅读 · 0 评论 -
SpringMVC的Controller中常用的三种返回值类型
https://blog.youkuaiyun.com/a909301740/article/details/80410660转载 2018-09-16 10:22:40 · 540 阅读 · 0 评论 -
java源码集合类注意事项
ArrayList:底层数组,线程不同步,扩容50%ArrayList.add()--每次add的时候会判断数据长度,如果不够的话会调用Arrays.copyOf,复制一份更长的数组,并把前面的数据放进去。 ArrayList.remove()--直接使用System.arraycopy把需要删除index后面的都往前移一位然后再把最后一个去掉。vector:线程同步,其iterator方...原创 2018-09-21 19:00:56 · 213 阅读 · 0 评论 -
编程思想—初始化
1.构造方法没有返回值,与返回void是不同的,虽然new表达式确实返回了对新建对象的引用,但构造器本身并没有任何返回值2.方法重载根据方法参数的类型和数量不同进行区分,与方法的返回值和权限修饰符无关。对于基本类型的方法重载,由于基本类型能够自动从一个较小的类型提升到一个较大的类型,因此当入参类型小于参数声明类型时,能够自动提升(如入参为int,声明为float,int会自动提升为floa...原创 2018-12-02 22:23:54 · 259 阅读 · 0 评论 -
操作符和流程控制
1. +号可以表示数字运算、字符串拼接、字符串转换(String+一个非String)的功能2. 逻辑操作符的短路——是指计算一串逻辑运算时如果前面部分已经满足了要求,后面的部分可能不再计算3. int a = 0xf; char b = 0xf; byte c = 0xf; short d = 0xf; ...原创 2018-11-28 21:28:38 · 163 阅读 · 0 评论 -
锁
https://blog.youkuaiyun.com/zqz_zqz/article/details/70233767转载 2018-11-01 15:47:16 · 113 阅读 · 0 评论