disruptor中生产者和消费者的相互引用和协作

本文描述了在一个disruptor中生产者和消费者之间是如何通过sequence进行协作的,以及如何通过sequence构建一个类似数据追赶模型的.
本文采用基本的一个生产者和一个消费者的处理模型进行描述.

所谓的追赶模型,即理解为2个数字A和B,当A要进行+1操作时,需要判断A<B,如果满足此条件,则可以进行操作,否则就等待,直到B进行操作从而满足条件A<B时才继续进行自身的操作.

从生产者/消费者模型来看,就相当于,生产者需要生产时,不再需要判断是否存在可存放的位置,而是判断要存放东西的位置是否还没有被消费,即生产位置 数<消费位置数;对于消费者,不再需要判断是否有没有被消费的物品,而是判断当前消费的数目是否小于生产的数目,即消费数<生产数.如果满 足,即获取指定位置的数据本身进行处理,然后自身位置数/数目+1操作,然后进行同样的处理.

这里面有2个区别的信息,位置数即在一个ringBuffer环中的下标值(最大值ringBuffer的长度),而数目则指不断的生产/消费的累积数(最大值Long.MaxValue).

以下分2个场景分别描述生产者通过持有消费者sequence用于进行生产判断,消费者通过持有生产者sequence用于进行消费判断.

继续阅读“disruptor中生产者和消费者的相互引用和协作”

安全有效地提升simpleDateFormat性能

    以下为转http://www.thedwick.com/blog/2008/04/simpledateformat-performance-pig/的一篇关于simpleDateformat中使用的一些误区以及怎么样来安全有效地使用simpleDateFormat。在本文中,描述了创造simpleDateFormat的昂贵代价,以及使用静态实例的多线程错误以及同步时的低效问题,并提出一个提升的解决办法。
    全文如下:

    Just yesterday I came across this problem “in the wild” for the third time in my career so far: an application with performance problems creating tons of java.text.SimpleDateFormat instances. So, I have to get this out there: creating a new instance of SimpleDateFormat is incredibly expensive and should be minimized. In the case that prompted this post, I was using JProfiler to profile this code that parses a CSV file and discovered that 50% of the time it took to suck in the file and make 55,000 objects out of it was spent solely in the constructor of SimpleDateFormat. It created and then threw away a new one every time it had to parse a date. Whew!

  “Great,” you think, “I’ll just create one, static instance, slap it in a field in a DateUtils helper class and life will be good.”
    Well, more precisely, life will be good about 97% of the time. A few days after you roll that code into production you’ll discover the second cool fact that’s good to know: SimpleDateFormat is not thread safe. Your code will work just fine most of the time and all of your regression tests will probably pass, but once your system gets under a production load you’ll see the occasional exception.
    “Fine,” you think, “I’ll just slap a ‘synchronized’ around my use of that one, static instance.”
    Ok, fine, you could do that and you’d be more or less ok, but the problem is that you’ve now taken a very common operation (date formatting and parsing) and crammed all of your otherwise-lovely, super-parallel application through a single pipe to get it done.
    What would be better is to use a ThreadLocal variable so you can have your cake and eat it, too:

继续阅读“安全有效地提升simpleDateFormat性能”

总结java内存数据的可见性和dcl的根本问题原因

    本文主要内容为网络收集,经过加工处理,参考文章见附录。
    说到java的并发编程,就必须要了解在并发中的一些数据的读取,特别是关键性数据的读取。为防止由于多线程的访问对于数据的读取产生读取顺序上的不一致,java引入了内存模型的概念,其根本概念即happen-before规则。

    happen-before规定在jvm实现内部,各个运行中的变量的读取顺序以及它对于多个线程在读取上的可见性。因为,在多个线程进行同时操作时,变量会根据每个线程保存它自己的一个副本(类似于clone),并且在必要的时候同主存(即原始的数据)同步一次。正是因为有这样的概念,在多线程中,我们看到的对象的数据值,可能就不是最新的一个数据值,而是一个过期的数据,或者说是一个错误的数据。而基于想象中正确的逻辑进行编程的话,就可能出现一些问题。
    happens-before就是“什么什么一定在什么什么之前运行”,也就是保证顺序性。即在多个线程或者同一个线程的不同操作之间,要满足说哪个操作一定会在哪个操作之前发生。那么在相对靠后的操作中使用的变量所读取的值,则一定是在操作之前写入的数据,不会读取到还未写入的值。

继续阅读“总结java内存数据的可见性和dcl的根本问题原因”