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

发布于 2024-11-09 11:56:48 字数 412 浏览 1 评论 0原文

给出以下代码

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

a() 中的线程在修改 x 的过程中是否可以被对同一对象调用 b() 的线程抢占?

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

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

有人可以解释一下吗?

Give the following code

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

Can the thread in a(), in the middle of modifying x be preempted by a thread that calls b() on the same object?

Isn't synchronized method be executed like one single atomic operation?

I believe the other way is possible(thread in b() can be preempted by the thread that calls a() on the same object since b() is not guarded my the Test object lock).

Can some one shed some light on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海夜未眠 2024-11-16 11:56:48

synchronized 仅阻止其他线程获取同一监视器。它不可能使操作原子化。特别是:

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

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

synchronized only stops other threads from acquiring the same monitor. It in no way makes the operation atomic. In particular:

  • Side-effects of the method can be observed by other threads which aren't trying to synchronize on the same monitor
  • If an exception occurs, there's no sort of roll-back
  • Other threads can access and modify the same data used by the synchronized method, if they aren't synchronized on the same monitor

b() isn't synchronized, so it's entirely possible for one thread to be executing a() and another to be executing b() at the same time.

吃颗糖壮壮胆 2024-11-16 11:56:48

由于 b() 不同步,而 a() 同步,因此有可能一个线程位于 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()

Since b() is not synchronized and a() is, it is possible for one thread to be in a() and the other to be in b(). So the value of x will most possibly be garbled due to parallel non-synchronized access to x.

In addition, if your code were like this:

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

and both of your threads are running on the same instance then there arises a possibility of Thread 1 [ currently in a() being preempted by Thread 2 [currently in b()].

However after Thread 1 is preempted, as Thread 2 tries to enter the a() method, the JVM will not allow it; since another thread [albeit a non running one] already has the lock on it. Hence now Thread 2 will be made to wait until Thread 1 completes execution of a() and returns. Then Thread 2 will [most probably] be brought back to life and allowed execution of a().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文