螺纹安全与安装;java信号量的原子性

螺纹安全与安装;java信号量的原子性,java,thread-safety,semaphore,atomic,Java,Thread Safety,Semaphore,Atomic,它们是如何实现的?我看过这个类的代码,它看起来不像任何类型的同步机制被用来确保线程安全或函数调用的原子性 我指的是类java.util.concurrent.Semaphore 编辑:请理解这绝不是错误报告或对java技术的不信任。而是一个让我理解的请求 了解这一点的最佳方法是查看nonfairTryAcquireShared(): compareAndSwapInt是一个本机函数,在我们的例子中,它保证了原子性,从而保证了同步。理解这一点的最佳方法是查看nonfairTryAcquireSha

它们是如何实现的?我看过这个类的代码,它看起来不像任何类型的同步机制被用来确保线程安全或函数调用的原子性

我指的是类
java.util.concurrent.Semaphore


编辑:请理解这绝不是错误报告或对java技术的不信任。而是一个让我理解的请求

了解这一点的最佳方法是查看
nonfairTryAcquireShared()


compareAndSwapInt
是一个本机函数,在我们的例子中,它保证了原子性,从而保证了同步。

理解这一点的最佳方法是查看
nonfairTryAcquireShared()


compareAndSwapInt
是一个本机函数,在我们的例子中,它保证原子性,从而保证同步。

简介

从更广泛的角度来看,问题在于任何锁定机制如何实现线程安全。由于这个问题有几个部分,我将一步一步地讨论

比较和交换(CAS)

是机器级别的指令,是编程级别的原子操作。现在,在您的特定信号量问题中,他们在从信号量访问许可证时使用此技术

  • 获取当前值
  • 计算新值
  • 通过传入当前值和新值执行CAS操作,查看该内存访问处的值是否为当前值,并将其与新值交换。如果它确实保存了我们注意到的当前值,则该值存储在内存位置,并返回true。如果它发现的值与预期的当前值不同,它将不会修改内存位置并返回false
  • AbstractQueuedSynchronizer

    该类是一个实现的类,用于在获取许可证时处理同步。该实现创建了一个队列(尽管可以使用不同类型的队列),并利用park/unpark技术来处理线程运行状态

    停车/Unpark

    当信号量中没有可用的许可证时,线程将停止。相反,一旦许可证可用(假设您正在使用FIFO实现,第一个线程将unparak),线程将CAS操作以获取许可证。如果失败,它将停驻,并重复该过程

    结论


    这些概念协同工作,通过机器级指令和编程操作利用原子性,确保一次只能由单个线程获取许可/锁,从而将线程对逻辑块的访问限制在所需的数量。

    简介

    从更广泛的角度来看,问题在于任何锁定机制如何实现线程安全。由于这个问题有几个部分,我将一步一步地讨论

    比较和交换(CAS)

    是机器级别的指令,是编程级别的原子操作。现在,在您的特定信号量问题中,他们在从信号量访问许可证时使用此技术

  • 获取当前值
  • 计算新值
  • 通过传入当前值和新值执行CAS操作,查看该内存访问处的值是否为当前值,并将其与新值交换。如果它确实保存了我们注意到的当前值,则该值存储在内存位置,并返回true。如果它发现的值与预期的当前值不同,它将不会修改内存位置并返回false
  • AbstractQueuedSynchronizer

    该类是一个实现的类,用于在获取许可证时处理同步。该实现创建了一个队列(尽管可以使用不同类型的队列),并利用park/unpark技术来处理线程运行状态

    停车/Unpark

    当信号量中没有可用的许可证时,线程将停止。相反,一旦许可证可用(假设您正在使用FIFO实现,第一个线程将unparak),线程将CAS操作以获取许可证。如果失败,它将停驻,并重复该过程

    结论


    这些概念协同工作,通过机器级指令和编程操作利用原子性,以确保每次仅由单个线程获取许可证/锁,将线程对逻辑块的访问限制在所需的数量。

    注意到
    类同步扩展AbstractQueuedSynchronizer
    信号量
    使用了一个(正如@assylias所说,我只是想链接到文档)。注意到
    类同步扩展AbstractQueuedSynchronizer
    信号量
    使用一个(正如@assylias所指出的,我只是想链接到文档)。
    final int nonfairTryAcquireShared(int acquires) {
            for (;;) {
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }
    
    protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }