队列是一种常用的数据结构,这片文章主要是介绍JDK中的非阻塞队列(ConcurrentLinkedQueue)的算法思想,你可以直接阅读JDK的源代码,也许你需要一些预备知识,例如unsafe类,你可以在这里(http://mishadoff.github.io/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/)找到它的资料,源码的注释中也给出了算法的出处(http://www.cs.rochester.edu/u/michael/PODC96.html),但JDK中的实现还是比较晦涩难懂的,也许我的描述可以节省你的许多时间,下面就开始了。
如果你还不了解CAS,可以参考http://blog.csdn.net/hsuxu/article/details/9467651
Unsafe
JDK源码中使用了Unsafe类,因此我在这里对用到的Unsafe类中方法做一个说明,给那些不想花太多时间研究Unsafe的同学节省时间。
Unsafe类提供了很多的方法来直接对内存地址进行读和写的操作,其中大部分的方法都是很底层的,可以对应到硬件指令,并且编译器也对这些方法做了大量的优化,因此效率非常的高。Unsafe中提供了getUnsafe方法来获取一个Unsafe的实例,典型的用法如下:
class MyTrustedClass {
private static final Unsafe unsafe = Unsafe.getUnsafe();
...
private long myCountAddress = ...;
public int getCount() { return unsafe.getByte(myCountAddress); }
}
但只能在JDK中的源码中使用,因为JDK之外的代码被认为是不被信任的,因此不能通过这种方式使用Unsafe。但你可以通过另一种方式使用它:
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
虽然如此,但我们是不应该在我们的应用代码中使用Unsafe的,原因很简单,对内存的直接操作始终都是非常危险的,如果你不想花太多的时间去定位这种问题的话,就不要使用它。下面介绍一下Unsafe中我们会用到的一些方法:
objectFieldOffset:给出指定字段的偏移量,这个偏移量是不变的,同一个类中不同的字段不会存在相同的偏移量&#