java - 在 Java 中使变量同步且可见

标签 java multithreading synchronization volatile

  1. 如果我在java中有一些同步方法,如何通过信号量实现相同的方法,而不需要同步? (假设该方法是变量增量)

  2. 如何在不使用synchronized关键字的情况下使某些变量对所有线程可见并同步?

最佳答案

1.If I have some synchronized method in java, how can I implement the same method by semaphores, without synchronized? (Let's say that the method is a variable increment)

您可以使用二进制信号量 (new Semaphore(1)),但您需要对以下问题有一个明确的答案为什么我要专门使用信号量?

虽然二进制信号量可用于互斥,但它们与互斥体并不完全相同,因为它们的主要用途主要与同步信号相关。例如,release() 不限于仅由最后成功获取许可的线程调用。

2.How can I make some variable visible to all threads and synchronized without using the synchronized keyword?

有很多方法可以做到这一点,但我不会一一列举,而是向您指出适用于几乎所有方法的底层语言机制。基本上,你需要保证the visibility, the ordering and the atomicity对变量所做的更改。

在程序执行中存在所谓的“发生在之前”顺序的概念,它可以用于推理在写入和读取时是否会看到什么值来自不同线程的变量。您可以说 happens-before 可用于保证对变量所做更改的可见性和顺序。

除此之外,您还需要确保此类更改的原子性。您需要知道存储是原子的,除了 longdouble 值,以及复合操作(例如使用 ++ 前缀递增或++ 后缀运算符)不是原子的。有多种方法可以解决这些问题,但除非您了解需要做什么,否则您将无法了解某人为您提供的解决方案如何工作(以及它是否正确)。

Java 语言规范的第 17 章(线程和锁),更具体地说,它的第 17.4 节(内存模型)更详细地解释了发生在之前是什么,以及您可以遵循哪些规则原因。

关于java - 在 Java 中使变量同步且可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36820822/

相关文章:

mysql - 将本地数据库数据同步到远程数据库

java - 为什么在第一种情况下会抛出 SessionFactory 异常?

java方法中的javascript变量生命周期

java - 将服务设置为从 Android 中的按钮调用

java - 使用 java 的经典有界缓冲区问题变体的同步问题

multithreading - IP扫描程序多线程中的关键部分

java同步和异常处理

Java 无效的流 header : 7371007E

java - 使用 run() 而不是 start() 启动线程

java 如果一次运行一个线程为什么需要同步