2
// In Thread1  
x=5;  
synchronization(obj)  
{  
    // do something (no operations involving x)  
}

// In thread 2  
synchronization(obj)  
{  
    // do something(operations involving x)  
}

是否有要求 JVM 在进入该块之前首先执行同步块之前的所有语句。在 Thread-1 中,由于同步块没有任何操作,x所以它可以先执行同步块,然后执行赋值操作x=5

xThread-2在其同步块中看到的值是什么。x = 0假设 Thread-1 首先执行,然后 Thread-2 执行,并且在创建 对象时它们都在同一个对象上运行。

我们可以说 Thread-1 中的同步块发生在 Thread-2 中的同步块之前。x那么Thread-2 在其同步块中的值应该是什么?

4

4 回答 4

3

是否有要求 jvm 在进入该块之前首先执行同步块之前的所有语句

是的。http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html说:

线程中的每个动作都发生在该线程中的每个动作之前,这些动作按程序的顺序出现在后面。

假设对 x 的赋值发生在第一个同步块执行之前,并且第一个同步块执行发生在第二个同步块执行之前,那么在第一个线程中分配给 x 的值将对第二个线程可见。(happens-before是及物的)。

于 2012-05-03T15:46:10.087 回答
0

您如何确保对 的更改x可见Thread 2

x不在Thread 1同步块中,我认为您没有成功volatile,因此即使x之前发生分配Thread 2Thread 2仍可能读取x.

于 2013-01-21T01:07:36.147 回答
0

在 Thread-2 中,x可能有几件事:

  • 0,如果 Thread-2 的同步块在之前运行(它也可能实际上在它之后运行,但之前缓存的值为 0,它没有义务更新,因为和 Thread-2x = 5之间没有发生之前的边缘)x = 5
  • 5,如果线程 2 的同步块在线程 1 的块之后x = 5(并且碰巧刷新了它的值)但在线程 1 的synchronized块之前运行
  • Thread-1 的synchronized块分配给的任何值x(在你的情况下不会发生,所以这个选项不可用)
  • 完全是其他一些值,如果x是 a longor double,因为这些类型中的单词不必自动更新。(见jls 17.7)。请注意,在这种特定情况下,“其他值”将是 0 或 5(如果您分别只看到 的上半部分或下半部分long)。但是,如果您的两个词的值都不是 0,那么您可以看到这些词的潜在值的任意组合。

在 Thread-1 中,正如 JB Nizet 指出的那样,线程内语义意味着您不会看到x未初始化的 0——它要么是 5,要么是 Thread-2 设置的任何值(当然也可以是 0) .

于 2012-05-03T16:00:25.367 回答
0
  1. 单个线程中的所有语句都按顺序执行。

  2. 您在第二个问题中描述的是竞争条件。线程 #1 将 a 值分配给同步块之外的 x。根据执行顺序,线程#2 可以看到 x = 0 或 x = 5;

  3. 对于您的第三个假设,x 将等于 5。

于 2012-05-03T16:03:24.707 回答