Java 我们可以在线程进入同步块后更改锁吗?

Java 我们可以在线程进入同步块后更改锁吗?,java,multithreading,Java,Multithreading,我问这个问题只是出于好奇,我知道做这样的事是愚蠢的 public void doSomething() { synchronized(object_A){ count++; average = count/total; } } 现在假设我有两个线程并发运行(调用函数doSomething()),当第一个线程已经进入块时,比如在“count++”行,第二个线程被阻塞并等待锁 现在我尝试在另一个线程中执行object\u A=new Loc

我问这个问题只是出于好奇,我知道做这样的事是愚蠢的

public void doSomething() 
{
      synchronized(object_A){
        count++;
        average = count/total;
      }
}
现在假设我有两个线程并发运行(调用函数doSomething()),当第一个线程已经进入块时,比如在“count++”行,第二个线程被阻塞并等待锁

现在我尝试在另一个线程中执行
object\u A=new LockObject()
。现在线程1和线程2会发生什么情况

线程2会进入块吗?既然它已经执行了语句“synchronized(object_A)”,那么更改锁是否太晚了


线程1是否会在同步块中更改锁(假设线程1仍在块中)

正如Igns所说,但是线程1完成后,线程2将看到新的引用,因为它必须刷新所有变量。

唯一的问题是数据完整性。线程将在不同的锁上同步,受锁保护的数据将具有错误的值。锁在实例初始值设定项的私有final字段或类的构造函数中创建。

线程1不会更改锁。它持有变量object_A引用的对象上的锁;一旦得到锁,它就会忘记变量。您甚至可以
synchronized(someMethod()){}
关于线程2,我猜(但我可能错了)它仍然会竞争第一个锁。说1。计算表达式,然后计算2。线程获得锁,但是3。当另一个线程持有锁时,一个线程不能执行2。因此,在我看来,线程2不会重新读取变量的引用,从而使变量赋值无效。无论如何,您应该注意,这里还有另一个问题-如果变量赋值不是易变的,那么它可能无效,并且赋值后不会发生同步。这是因为线程被允许创建变量的本地副本,并且只需要在volatile/synchronized上更新这些本地副本。这是关于我对volatile/synchronized的第三条评论,我同意线程2将看到更新的变量。但这并不意味着线程2将锁定新对象,请参阅我对jls的第二条评论。