繁体   English   中英

抢占正在执行同步方法的线程

[英]Preempting a thread that is executing synchronized method

给出以下代码

    class Test{
       double x;
       public void synchronized a()
       { 
          x = 0;
          //do some more stuff
       }
       public void b() 
       { 
          x = -1; 
       } 
    }

a() 中的线程能否在修改 x 的过程中被同一个 object 上调用 b() 的线程抢占?

同步方法不是像单个原子操作一样执行吗?

我相信另一种方式是可能的(b() 中的线程可以被在同一个 object 上调用 a() 的线程抢占,因为 b() 不受我的测试 object 锁的保护)。

有人可以对此有所了解吗?

synchronized仅阻止其他线程获取相同的监视器。 绝不会使操作成为原子操作。 尤其是:

  • 该方法的副作用可以被其他未尝试在同一监视器上同步的线程观察到
  • 如果发生异常,则没有任何回滚
  • 其他线程可以访问和修改同步方法使用的相同数据,如果它们不在同一个监视器上同步

b()不同步,因此一个线程完全有可能同时执行a()而另一个线程同时执行b()

由于b()不是同步的,而a()是同步的,因此一个线程可能在a()中,而另一个线程在b()中。 因此,由于对x x值很可能会出现乱码。

此外,如果您的代码是这样的:

class Test{
       double x;
       public void synchronized a()
       { 
          x = 0;
          //do some more stuff
       }
       public void b() 
       { 
          x = -1; 
          a(); //added call to a()
       } 
    }

并且你的两个线程都在同一个实例上运行,那么就有可能线程 1 [当前在a()中被线程 2 [当前在b()中] 抢占。

但是在线程 1 被抢占后,由于线程 2 尝试进入a()方法,JVM 将不允许它; 因为另一个线程[尽管不是正在运行的]已经锁定了它。 因此,现在线程 2 将等待,直到线程 1 完成a()执行并返回。 然后线程 2 [最有可能] 将恢复活力并允许执行a()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM