使变量在Java中同步和可见[关闭]

问题描述 投票:1回答:2
  1. 如果我在java中有一些同步方法,我如何通过信号量实现相同的方法,而不是同步? (假设该方法是一个变量增量)
  2. 如何在不使用synchronized关键字的情况下使一些变量对所有线程可见并同步?
java multithreading synchronization volatile
2个回答
1
投票

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

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

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

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

有很多方法可以做到这一点,但不是枚举它们,我将指出几乎适用于所有这些方法的基础语言机制。基本上,您需要保证the visibility, the ordering and the atomicity对您的变量所做的更改。

在程序执行过程中所谓的发生 - 操作顺序排列之前的概念,它可以用来推断当你从不同的线程写入和读取变量时,你会看到什么值。您可以说之前发生的事件可用于保证对变量所做更改的可见性和顺序。

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

Java语言规范的第17章(线程和锁),更具体地说,它的第17.4节(内存模型)更详细地解释了之前发生的事情以及您可以在其中推理的规则。


0
投票

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

将信号量作为实例变量并使用值1进行初始化。当您输入方法时获取它并在退出时释放它。这应该在try-finally块中实现,以确保释放发生。

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

您可以使用并发库中可用的锁,也可以将其设置为volatile变量,以确保写入对所有线程立即可见。但是,如果多个线程可以写入此volatile变量,您仍然需要额外的同步。

© www.soinside.com 2019 - 2024. All rights reserved.