这是一个场景
我们有两个线程都访问同一段代码,并且该代码有一个变量,例如
int a = 200;
线程A输入并将其值更改为a = 300;
然后线程B访问这个变量,线程B得到200还是300?
答案 0 :(得分:2)
不保证两个线程以任何固定顺序执行; A中的任何操作都可以在B中的任何操作之前(假设操作仍在其自己的线程中顺序流动)。
因此,如果没有同步,A可能会在B访问它之前或之后更改其值。如果A在B之前改变它,则B看到300;否则,B看到200。
答案 1 :(得分:1)
下面的状态图表描述了线程状态。
Thread.sleep(milliseconds), Thread.sleep(milliseconds, nanoseconds);
关于你的例子,我们不知道线程B将占用200或300.如果你同时启动两个线程,因为你的方法将被同步,线程B应该看到200(如果它将是第一个或300)。
答案 2 :(得分:1)
由于编译器优化,线程可以缓存数据,第二个线程可能看不到第一个线程更改。这就是“volatile”用于共享数据以避免多线程环境中的问题
附录 - 我说的是线程中变量变化的可见性,而不是同步。
答案 3 :(得分:0)
如果你的线程同时访问你的代码,它将根据jvm级别的线程优先级发生。我们无法保证哪个线程将访问代码。如果它是同步的,则线程B必须等到线程A释放资源。
答案 4 :(得分:0)
上述执行的结果取决于一致性模型。
在顺序一致性模型中,执行的结果是所有指令都以某种全局顺序执行。在这种情况下,threadB将获得值300.
但是,现代机器使用较弱的一致性模型,其中所有同步(内存栅栏指令)操作仅以全局顺序顺序发生。
如果在threadA的存储完成后发生了threadB的加载,则threadB将获得值= 300.这由高速缓存一致性协议保证。 但是,如果threadB的加载指令发生在threadA的存储之前/之后(由于某些优化),则threadB中的共享变量的值是未定义的。这将是在总线操作中threadB的加载和threadA的存储之间的竞争条件的结果。