如果我在同一个类上同步两个方法,它们可以同时运行吗?
如果我在同一个类上同步两个方法,它们可以同时在同一个对象上运行吗? 例如:
class A { public synchronized void methodA() { //method A } public synchronized void methodB() { // method B } }
我知道我不能在两个不同线程的同一个对象上运行两次methodA()
。 methodB()
同样的事情。
但是,我可以在methodB()
仍在运行时在不同的线程上运行methodB()
吗? (同一个对象)
这两种方法locking相同的监视器。 因此,不能同时在不同的线程中执行同一个对象(两个方法中的一个会阻塞,直到另一个完成)。
synchronized
一个方法意味着线程必须在进入该方法之前获得对象实例上的locking,因此如果有两个标记为同步的方法,则进入它们的线程将争夺同一个锁,一旦一个线程获得锁所有其他线程都会被同一个锁同步的所有方法拒之门外。 所以为了使这两个方法同时运行,他们必须使用不同的锁,如下所示:
class A { private final Object lockA = new Object(); private final Object lockB = new Object(); public void methodA() { synchronized(lockA) { //method A } } public void methodB() { synchronized(lockB) { //method B } } }
Java Thread在进入实例同步java方法时获取对象级锁 ,并在进入静态同步java方法时获取类级锁 。
在你的情况下,方法(实例)是相同的类。 所以当一个线程进入到java synchronized方法或者block中时,它会获得一个锁(这个方法被调用的对象)。 所以其他的方法不能同时在同一个对象上被调用,直到第一个方法完成并且locking(在对象上)被释放。
在你的情况下,你在同一个类的实例上同步两个方法。 所以,这两个方法不能同时在同一个A类实例的不同线程上运行,而是可以在不同的A类实例上运行。
class A { public synchronized void methodA() { //method A } }
是相同的:
class A { public void methodA() { synchronized(this){ // code of method A } } }
为了清楚起见,静态同步方法和非静态同步方法都可以同时运行或同时运行,因为有一种方法是有对象级别locking和其他类级别的locking。
从oracle文档链接
使方法同步有两个作用:
首先,同一个对象上的两个同步方法的调用是不可能交错的。 当一个线程正在执行一个对象的同步方法时,所有其他调用同一对象的同步方法的线程将阻塞(挂起执行),直到第一个线程完成对象。
其次,当一个同步的方法退出时,它会自动build立一个与先前同步对象的任何后续调用同步方法的before-before关系。 这保证了对所有线程都可见的对象状态的改变
这将回答你的问题:在同一个对象上,当第一个同步方法执行正在进行时,你不能调用第二个synchronized方法。
看看这个文档页面了解内部锁和locking行为。
你正在对象而不是课堂上同步它。 所以他们不能同时运行在同一个对象上
两个不同的线程在单个对象上执行一个通用的同步方法,因为对象是相同的,所以当一个线程使用同步方法时,它必须对锁进行变化,如果启用了锁,这个线程将进入等待状态,如果锁被禁用,那么它可以访问该对象,而它将访问该对象将启用该锁,并且只有在其执行完成时才释放该锁。 当另一个线程到达时,它会变化锁,因为它被启用,它将等待,直到第一个线程完成其执行并释放对该对象的锁,一旦锁被释放,第二个线程将获得对该对象的访问并且它将启用锁,直到它的执行。 所以执行不会是并发的,两个线程都会一个一个的执行,当线程在不同的对象上使用synchronized方法时,它们将同时运行。