Sud*_*dix 8 java multithreading
程序大纲:
我们有两个线程(t1和t2)写一个整数值,然后将写入的值刷新到RAM.
另一个线程(t3)检查值巧合与所述一个是否写t1或t2,如果没有,打印它.
public class Container
{
int a;
volatile boolean b;
public static void main(String[] args)
{
Container container = new Container();
Thread t1 = new Thread()
{
@Override
public void run()
{
for (;;)
{
container.a = 409;
container.b ^= container.b;
}
}
};
Thread t2 = new Thread()
{
@Override
public void run()
{
for (;;)
{
container.a = 102;
container.b ^= container.b;
}
}
};
Thread t3 = new Thread()
{
@Override
public void run()
{
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
for (;;)
{
if (container.a != 409 && container.a != 102 )
System.out.println(container.a);
}
}
};
t1.start();
t2.start();
t3.start();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为会发生什么:
既然a不是volatile,我认为t3会缓存a,永远不会打印任何东西.
实际发生的事情:
大约一秒左右(无论你多久都t3睡不着),它会快速连续打印102或409.然后,打印停止(永远).
这到底发生了什么?
biz*_*lop 11
container.a不易挥发并不意味着它被强制缓存t3.这意味着无论是否存在都无法保证.
可以自由打印任何值的原因是此处的使用时间检查问题:
if (container.a != 409 && container.a != 102 )
System.out.println(container.a);
Run Code Online (Sandbox Code Playgroud)
至于为什么在你测试它的确切环境中的这种确切行为,我们只能猜测.但我的理由是,虽然代码是按解释运行的container.a,但它每次都会进行读取,但是一旦Hotspot将其编译为本机代码,该值只会加载到寄存器中一次,这就是结束它.您可以使用-XX:+PrintCompilation命令行标志来验证此假设.