使变量在Java

时间:2016-04-24 08:20:25

标签: java multithreading synchronization volatile

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

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

2 个答案:

答案 0 :(得分:1)

  

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

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

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

  

2.如何在不使用synchronized关键字的情况下为所有线程显示某些变量并进行同步?

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

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

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

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

答案 1 :(得分:0)

  

如果我在java中有一些同步方法,我该如何实现   信号量相同的方法,没有同步? (让我们说吧   方法是一个变量增量)

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

  

如何使一些变量对所有线程可见并且已同步   不使用synchronized关键字?

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