2013-04-02 52 views
1

如果类A有两个同步方法,比如methodA和methodB。如果一个线程访问methodA,另一个线程是否可以访问methodB?根据我的理解,当访问methodA时,线程获取对象的锁定,另一个线程不应该同时访问methodB。但是这会降低性能,对吧?而且,我似乎习惯读一篇文章说另一个线程可以访问methodB。哪一个是正确的?java如何同步工作

+0

取决于您使用的锁。如果该方法是同步的,则在执行时只有一个线程可以访问它。 – Shark

回答

5

如果A类有两个同步方法,比如methodA和methodB。如果一个线程访问methodA,另一个线程是否可以访问methodB?根据我的理解,当访问methodA时,线程获取对象的锁定,另一个线程不应该同时访问methodB。

没错;如果一个线程持有该对象的锁,则其他线程必须等待才能获得该锁。当然,如果两个线程都在完全相同的对象上调用方法,情况就是如此。

但是这会降低性能很多,对吧?

它可能会影响性能,但有时例如有必要防止两个线程同时修改相同的数据。

而且,我似乎用来阅读一篇文章,说另一个线程可以访问methodB。哪一个是正确的?

第一个是正确的,第二个是不正确的。

1

但是这会降低性能很多,对吧?

它可能或不可能。这取决于应用程序的性质。同步成本可能接近于零,也可能是一个主要瓶颈,有效地将多线程应用程序转变为单线程应用程序。

参见Amdahl's Law

而且,我似乎用来阅读一篇文章,说另一个线程可以访问methodB

没有其他线程可以在同一个对象上调用methodBmethodA运行。当然,其他线程可以在同一类的其他实例上自由呼叫methodB

+0

>接近零成本 - 即使不需要同步,也几乎不会接近于零。你可以比较ArrayList和Vector类的性能来看看 – popfalushi

+0

为了证明我做了一个实验的一点。代码和结果在下面的注释代码中:http://pastebin.com/UzxdzvV4。 Arraylist.add比Vector.add快2-3倍,这是ArrayList的同步版本。 – popfalushi

+0

@popfalushi说你有很多线程在执行缓慢的磁盘操作,并将它们的结果存储在单个对象中......同步的开销几乎为零,对吗? –