ThreadLocal Java多线程下的影分身之术

  如果写过多线程的代码,你肯定考虑过线程安全问题,更进一步你可能还考虑在在线程安全的前提下性能的问题。大多数情况下大家用来解决线程安全问题都会使用同步,比如用synchron或者concurrent包提供的各种锁,当然这些都能解决问题。但有多线程做同步一定会涉及到资源争抢和等待的问题。java中各种同步方法都是提供一种准入机制,JVM会调用系统同步原语来保证临界区任意时刻只能有一个线程进入,那必然其他线程都得等待了,性能的瓶颈就在这同步上了。
Continue reading

Java WeakHashMap

  作为一个java开发者肯定都知道且使用HashMap,但估计大部分人都不太知道WeakHashMap。从类定义上来看,它和普通的HashMap一样,继承了AbstractMap类和实现了Map接口,也就是说它有着与HashMap差不多的功能。那么既然jdk已经提供了HashMap,为什么还要再提供一个WeakHashMap呢? 黑格尔曾经说过,存在必合理,接下来我们来看下为什么有WeakHashMap。
Continue reading

Java弱引用(WeakReferences)

  前一段时间当我面试有些来应聘高级java开发工程师岗位的候选人时,在我问的众多问题中,有个问题是“你能告诉我弱引用是啥吗”,我不期望得到像论文中的细节一样的答案。我很可能从有个20多年的老工程师口中得到“嗯……是不是和gc有关”这样的答案,所有哪些至少有5年以上经验的工程师只有两个人知道弱引用的存在,只有其中一个知道引用的相关知识。我甚至尝试给他们解释下看是否有人会有“哦,原来是这样”的反应,然而并没有。我不确定为啥这个知识点鲜为人知,但自Java1.2之后发布的弱引用确实是有个非常有用的功能。
Continue reading

Spring依赖注入的三种方式(好的 坏的和丑的)

  关于spring bean三种注入方式的优缺点对比,翻译自Spring DI Patterns: The Good, The Bad, and The Ugly,水平有限,如有错误请指正。
  Spring开发者会很熟悉spring强大的依赖注入API,这些API可以让你用@Bean的注解让Spring实例化和管理Bean。Bean之间的任何依赖都会被spring解析和注入。
Continue reading

java.util.Random和concurrent.ThreadLocalRandom对比

  最近工作中遇到了一个需求,需要以一定的概率过滤掉一部分的流量,想想只能用Random了,因为是在多线程环境下,我还特意确认了下Random在多线程是否能正常运行,Random的实现也比较简单,初始化的时候用当前的事件来初始化一个随机数种子,然后每次取值的时候用这个种子与有些MagicNumber运算,并更新种子。最核心的就是这个next的函数,不管你是调用了nextDouble还是nextInt还是nextBoolean,Random底层都是调这个next(int bits)。
Continue reading

Java生产者消费者的三种实现

  Java生产者消费者是最基础的线程同步问题,java岗面试中还是很容易遇到的,之前没写过多线程的代码,面试中被问到很尬啊,面完回来恶补下。在网上查到大概有5种生产者消费者的写法,分别如下。

  1. 用synchronized对存储加锁,然后用object原生的wait() 和 notify()做同步。
  2. 用concurrent.locks.Lock,然后用condition的await() 和signal()做同步。
  3. 直接使用concurrent.BlockingQueue。
  4. 使用PipedInputStream/PipedOutputStream。
  5. 使用信号量semaphore。  
    Continue reading

Java线程间同步(诡异的IllegalMonitorStateException )

  前两天去面试,被问到了一个线程同步的问题,两个线程依次输出1……100,一个线程只输出奇数,一个只输出偶数。之前工作中没写过线程同步的代码,只知道使用object的wait()和notify()方法可以实现线程同步,之前也看过线程池实现的代码,用的也是wait()和notify()。 面试过程中没写出来,于是想回来学习下多线程的同步,然后就有了今天这诡异的事。
Continue reading

Java线程的使用方法

  大学的时候就顾着搞acm了,没写过工程,尤其是多系统协作的工程。工作中遇到一种场景,我自己代码需要多次调用别的系统api,http的接口rt在几十毫秒左右,我必须在几百毫秒内完成上百次的查询,串行的单线程代码不可能完,所以不可避免需要使用到线程,在java里线程的实现方方式有三种 Runnable Thread Callable。
Continue reading