Java 什么';“的影响是什么?”;私有静态最终VarHandle挂起“;在CountedCompleter类中

Java 什么';“的影响是什么?”;私有静态最终VarHandle挂起“;在CountedCompleter类中,java,atomic,java-9,compare-and-swap,Java,Atomic,Java 9,Compare And Swap,我正在阅读JDK9中的CountedCompleter源代码,下面是与我的问题相关的代码: 公共抽象类CountedCompleter扩展了ForkJoinTask{ /**完成前的挂起任务数*/ 易失性int待定; //瓦汉德尔力学 私有静态最终VarHandle挂起; 静止的{ 试一试{ MethodHandles.Lookup l=MethodHandles.Lookup(); PENDING=l.findVarHandle(CountedCompleter.class,“PENDING”

我正在阅读JDK9中的
CountedCompleter
源代码,下面是与我的问题相关的代码:

公共抽象类CountedCompleter扩展了ForkJoinTask{
/**完成前的挂起任务数*/
易失性int待定;
//瓦汉德尔力学
私有静态最终VarHandle挂起;
静止的{
试一试{
MethodHandles.Lookup l=MethodHandles.Lookup();
PENDING=l.findVarHandle(CountedCompleter.class,“PENDING”,int.class);
}捕捉(反射操作异常e){
抛出新异常初始化错误(e);
}
}
/**
*将挂起计数设置为给定值。
*
*@param数一数
*/
公共最终无效设置PendingCount(整数计数){
待定=计数;
}
/**
*将给定值(原子地)添加到挂起计数。
*
*@param delta要添加的值
*/
公共最终无效addToPendingCount(整数增量){
待定。getAndAdd(本,delta);
}
/**
*如果挂起计数非零,(原子地)递减它。
*
*@返回初始(未删除)待处理计数在条目中保留
*对这种方法
*/
公共最终整数递减PendingCountUnlessZero(){
INTC;
do{}while((c=pending)!=0&&
!PENDING.weakCompareAndSet(this,c,c-1));
返回c;
}
}
以下是我的问题:

  • 为什么使用挂起和
    挂起
    ?为什么不使用类似于原子整数的东西呢
  • 为什么有时它使用挂起,例如在
    setPendingCount()
    中,但有时它使用
    pending
    ,例如在
    addToPendingCount()
    中。它甚至在
    decrementPendingCountUnlessZero()中使用了这两种方法
  • 为什么使用pending和pending

    前者是字段,后者是字段的句柄,用于对字段执行原子操作

    为什么不直接使用像AtomicInteger这样的东西呢

    他们可以。我怀疑这只是性能问题。并发API的大多数部分都经过了大量优化,因为它们很可能涉及到紧密循环

    AtomicInteger
    UndertheHood做的事情基本上与这里确保原子操作所做的事情相同,因此使用它将是方法调用的一个间接层次,只需少量的复制粘贴即可实现冗余。是的,性能提升非常微小,但对于一些专门的应用程序来说,这是值得的

    是的,重新使用
    AtomicInteger
    会使代码更简洁,但是并发API中的目标与您或我的项目中的目标不同。性能是首要的,其他一切都是次要的

    为什么有时它会使用
    pending
    ,例如在
    setPendingCount()
    中, 但有时它会使用
    PENDING

    它将volatile字段直接用于已经是原子的操作
    setPendingCount
    只分配给字段

    public final void setPendingCount(int count) {
        pending = count;
    }
    
    在其他需要比较和设置的情况下,需要像原子操作一样运行,
    VarHandle
    提供了该功能

    public final boolean compareAndSetPendingCount(int expected, int count) {
        return PENDING.compareAndSet(this, expected, count);
    }
    
    它甚至使用这两种方法,例如在
    递减结束计数unlesszero()

    同样,答案是原子性。他们用这种方法编写它的方式是实现该函数原子性的最有效的方式