java这个同步块中发生了什么
我试图查看变量值是否可以在synchronized
块之前由多个线程修改。我对下面代码的行为感到困惑。我创建了一个具有synchronized
块的方法,如下所示
public void testMethod( String x )
{
String myX = x.toUpperCase();
System.out.println( myX ); // Prints the value before the critical section
synchronized( this )
{
try
{
Thread.sleep( 5000 );
}
catch( InterruptedException e )
{
e.printStackTrace();
}
System.out.println( myX ); // Prints the value inside the critical section
}
}
然后,我创建了两个线程,用两个不同的字符串值调用这个方法,如下所示
Thread myThreadOne = new Thread( () -> testMethod( "T1" ) );
Thread myThreadTwo = new Thread( () -> testMethod( "T2" ) );
并在主方法中调用
public static void main( String[] args )
{
Test t1 = new Test();
t1.myThreadOne.start();
t1.myThreadTwo.start();
}
现在我期望的输出是T1
、T2
、T2
、T2
、T2
。或者,无论哪个线程最后启动,都应该在synchronized
块之前和内部打印该值,因为很明显,变量myX
将在第一个线程处于睡眠状态或第一个线程处于临界段内时具有来自第二个线程的更新值
但是输出总是第一个线程值,然后是第二个线程值。像T1
,T2
,T1
,T2
。这是怎么发生的?VaribalemyX
在synchronized
块之外,不是第二个线程修改此值。还是我的示例代码有问题
# 1 楼答案
您需要在
method
之外声明myx
变量:这将给你你想要的结果
原因:
你可以看看这个:Why are local variables thread safe in Java
# 2 楼答案
字符串myX是一个局部变量,这意味着当每个线程执行testMethod(字符串x)时,它将创建一个对任何其他线程都不可见的唯一副本
如果你想改变myX,我建议你使用一个全局变量