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" ) );
并在 main 方法中调用。
public static void main( String[] args )
{
Test t1 = new Test();
t1.myThreadOne.start();
t1.myThreadTwo.start();
}
现在我期待的输出是T1
, T2
, T2
, T2
。或者无论哪个线程最后开始都应该在块之前和内部打印值,synchronized
因为很明显,myX
当第一个线程处于睡眠状态或第一个线程在临界区内时,该变量将具有来自第二个线程的更新值。
但输出始终是第一个线程值,然后是第二个线程值。像T1
, T2
, T1
, T2
. 这是怎么发生的?变量myX
在synchronized
块外,不是第二个线程修改这个值。还是我的示例代码有问题?
解决方案
您需要在以下范围内声明myx
变量method
:
String myX;
public void testMethod( String x )
{
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
}
}
这将为您提供所需的结果。
为什么 :
- 局部变量本质上是线程安全的,不被线程共享
- 虽然类变量是共享的
推荐阅读
- javascript - 如何让用户在 React 中下载数据(CSV)?
- anaconda - 从 .yml 文件创建 conda 环境 - 错误报告
- django - TypeError: $(...).dropzone 不是函数
- c# - 测试保存在 ASP.NET 2.2 中正确文件夹中的 IFormFile
- apache - 如何使用自签名 openssl 证书为多个域设置 Apache httpd 服务器
- python-3.x - 有没有办法从下面的每一行字符串中提取“公司名称”“职位名称”和“职位位置”
- reactjs - 布尔玛没有在 Gatsby 中填充 className
- google-chrome-extension - 关闭chrome标签后保存数据的确认框?
- node.js - 我在使用 mocha 和 typescript 时遇到未定义的错误
- python-3.x - 你如何在python中显示来自外部文件的最高平均分排序的平均分数和名称,知道同一个名字可以出现多次?