Bulingfeng Blog

「背后的努力决定人生的高度」

并发容器

并发容器

简介 任何一个java的容器都可以使用Collections类提供的synchronizedXXX()函数来把对应的容器转换为线程安全的容器,但是这种加锁是简单粗暴的,性能比较低下。 而JUC(java util concurrent)提供的一些并非容器,虽然不能和java的容器一一对应,但是由于使用了分段锁,所以可以高效的执行代码。 写时复制 当多线程写一个容器的时候(多个增,...

原子类介绍

原子类介绍

简介 原子类都是使用CAS的方式来进行实现的,而原子类的分类如图所示;由于浮点数不能精确确定其的准确值,所以没有浮点类的原子类。 ABA问题 当引用类型的数据被修改的时候会出现ABA问题,这样会造成一些问题。所以原子类也给了对应的类来防止这种现象出现,比如AtomicStampedReference。 1 2 3 4 5 6 AtomicStampedReference<S...

ThreadLocal的详细描述

ThreadLocal的详细描述

简介 多线程出现线程安全的重要原因就是共享变量,如果没有共享变量,那么也就不存在线程安全的问题。而ThreadLocal可以从感觉上来让某些变量变成共享,但是又是线程安全的。 这个因为是感觉上是共享,只不过是都是同一个线程执行的时候才能拿到同样的共享数据,虽然没有显式的调用。 这是因为Thread类中有个成员变量ThreadLocal.ThreadLocalMap threadLoca...

常见问题总结

常见问题总结

关于ThreadLocal问题 ThreadLocal在使用结束的时候,要强制调用remove方法来进行把对应线程持有的ThreadLocalMap的引用给释放掉,否则会引起OOM。 tomcat为共享线程池,然后ThreadLocal没有主动调用remove方法导致内存泄露 没有主动调用remove方法,由于tomcat是线程池复用,所以造成同一个线程中的用户信息不一致。比如...

ReentrantReadWriteLock总结

ReentrantReadWriteLock总结

简介 ReentrantLock虽然已经能够实现锁的灵活控制,但是有个缺陷就是假如有读和写的两个方法,想通过保证读的值是准确的,写的值也是准确的。ReentrantLock虽然也能够实现,但是读和写总是互斥的,从而降低了程序的效率。 而ReentrantReadWriteLock有两把锁:读锁和写锁。这个锁的好处就是多个线程的读是可以并行的,但是多个线程的读和写是不行的,当然多个线程的写...

AQS底层原理和ReentrantLock实现

AQS底层原理和ReentrantLock实现

简介 虽然synchronized和ReentrantLock在性能上已经差别很小,但是ReentrantLock有很多特性是synchronized没有的特性。 共同点 都支持重入锁(实际上java的锁都支持重入锁,否则会造成很多死锁的情况) ReentrantLock特有特性 设置锁是否是公平锁 可中断锁;这意味着在获取锁的时候,可以进行中断 判断是否获取...

java中的锁

java中的锁

锁的简介 java中有两种锁synchronized和lock;原来synchronized被认为是低效的,但是经过一些优化之后和lock的性能已经相差无几了。 synchronized synchronized可以用于方法和方法内的局部代码块。 synchronized使用的是Monitor锁,而Monitor锁是跟着对象走的。 作用与方法 add和substrac...

JMM(可见性-原子性-重排序)

JMM(可见性-原子性-重排序)

可见性 造成可见性的最根本原因是CPU缓存,并且还是多核CPU下的缓存。换而言之如果是单CPU的缓存则不会存在可见性问题。 重排序 下面的代码有可能先执行ready = true; 然后再执行value=2,从而导致的结果就是t1线程输出的结果为1。 重排序也只会在多线程情况下才有可能发生问题的(请注意是多线程,不用关心CPU是否是多核)。 1 2 3 4 5 6 ...

动态代理

动态代理

简介 代理分为两种,一种是静态代理,一种是动态代理。 静态代理:在编译的时候生成代理类的字节码; 动态代理:在程序运行的过程中生成代理类的字节码; 使用静态代理的时候,需要有个代理类和原来要加强的逻辑都有同样的接口,然后代理类通过实现接口来对想要操作的方法进行加强。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public interface IU...

java异常

java异常

异常体系 直接继承Exception的异常是受检异常(checked Exception)或编译时异常(Compile Exception); 直接继承RuntimeException的异常是非受检异常(unchecked exception) 为何高并发下太多异常会导致程序变慢? 因为异常是一个调用链,这个链中就是每个方法挨个调用的方法栈;这就是解释了为什么发...