【问题标题】:Various java threads accessing same variable访问同一个变量的各种java线程
【发布时间】:2014-04-24 15:15:56
【问题描述】:

如果我有 10 个左右的线程访问同一个变量(只读取它,不写入),java 是否会允许这些线程同时读取变量,或者每个线程都会排队等待读取?

我对标准行为感兴趣,即没有特别注意访问变量。

程序在 Linux RedHat 上运行。

【问题讨论】:

  • 他们会同时阅读。据我了解,一些线程甚至可能会缓存它。
  • 如果没有同步或其他锁定机制,则应该同时访问。对于 volatile 也是如此,但在这里访问主堆内存会产生额外的成本。
  • 没有读取队列。读取访问是模拟运行线程,即使该字段是易失性的(前提是没有写入)。

标签: java linux multithreading shared-memory


【解决方案1】:

理想情况下,它会同时读取它,但在某些情况下并不安全。

例如, 如果你声明:

int i = 1;

Thread threadOne = new Thread() {
public void run() {
    i++;
    System.out.println("ThreadOne is " + i);
}
};

Thread threadTwo = new Thread() {
public void run() {
    i++;
    System.out.println("ThreadTwo is "+ i);
}
};

Thread threadThree = new Thread() {
public void run() {
    i++;
    System.out.println("ThreadThree is " + i);
}
};

threadOne.start();
threadTwo.start();
threadThree.start();

您可以尝试多次,您会看到结果各不相同。 如果没有同步,所有线程将“随机”或“同时”读取和写入内存,这取决于谁先完成。

程序运行几次后得到的结果:

ThreadOne is 1
ThreadThree is 3
ThreadTwo is 2

ThreadOne is 3
ThreadThree is 3
ThreadTwo is 3

ThreadTwo is 2
ThreadThree is 3
ThreadOne is 2

正如我们所看到的,所有三个线程都随机读取包含 int i 的内存并通过添加一个来更新 int a。如果一个线程添加了一个,那么另一个线程将读取 2。

system.out.println() 也是一个进程。在第二次尝试中,它打印所有 3。 意思是三个线程读完int i加1后,int i的最终结果变成了3,那么system.out.println都会打印出3。这里用另一种方式来证明,在所有这些线程中,所有的进程都是同时运行或线程同时运行。

【讨论】:

  • 不错的示例,我们可以做更多工作。尝试在每个 i++ 之前加上不同时间参数的 sleep(),我想你会得到更有趣的结果。
  • 如果示例显示的情况更类似于@filippo 所要求的情况,当您在那段时间只进行读取而没有写入时,可能会有所帮助。
  • @NESPowerGlove 我认为 i++ 包含读写,我会更新我的答案。
  • 确实如此,我的意思是在句子的最后一部分描述@filippo 要求的情况,他想知道在没有写入但读取的情况下会发生什么。跨度>
【解决方案2】:

如果您允许多个线程不使用同步,则可以读取相同的值。虽然如果您不更改值,请确保所有 10 个线程在长时间读取之前都看到最新值(可能是初始值)(这需要至少同步一次)。

【讨论】:

    【解决方案3】:

    是的,读取和写入将同时完成,为了更加一致,您应该将volatile 关键字添加到您的变量中。它仍然没有锁,但是如果将来您想以某种方式进行一些更一致的写操作。

    【讨论】:

      猜你喜欢
      • 2013-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多