public synchronized void someSynchronizedMethod() {
...
someNonSynchronizedMethod();
...
}
// anyone can call this method even if the someSynchronizedMethod() method has
// been called and the lock has been locked
public void someNonSynchronizedMethod() {
...
}
4条答案
按热度按时间nle07wnf1#
如果线程a调用了同步方法m1,而同步方法m1又调用了非同步方法m2,那么线程b仍然可以在不阻塞的情况下调用m2。
synchronized方法获取并释放调用它的对象上的内在锁。这就是它可能阻塞的原因。unsynchronized方法不会尝试获取任何锁(除非在代码中显式完成)。
因此,如果您还需要确保m2的互斥性,那么应该使其同步,而不管其调用者(如m1)是否同步。
rqqzpn5f2#
锁属于线程,而不是方法(或者更准确地说,是它的堆栈帧)。碰巧的是,如果您有一个同步的方法,那么可以保证线程在方法体启动之前拥有锁,然后释放它。
另一个线程仍然可以调用第二个非同步方法。任何线程都可以随时调用未同步的方法。
esyap4oy3#
锁不属于线程。锁实际上属于对象(或类级别锁中的类),线程在同步上下文中获取对象(或类级别锁中的类)上的锁。现在,java中没有锁传播,正如上面讨论的那样。下面是一个小演示:
只是我在这里用了重入锁。如果运行了上述代码,那么线程1和线程3之间将进行交错,但是如果task2类的锁部分没有注解,那么将不进行交错,并且首先获取锁的线程将首先完全完成,然后它将释放锁,然后另一个线程可以继续。
eqzww0vc4#
如果一个同步方法调用另一个非同步方法,那么该非同步方法上是否有锁
是和否。
如果你身处困境
synchronized
方法,然后由其他线程调用同一对象示例的其他方法synchronized
锁上了。但是,其他线程对非同步方法的调用不会被锁定—任何人都可以同时调用它们。另外,如果你打电话
someSynchronizedMethod()
但恰好在someNonSynchronizedMethod()
方法,你仍然持有锁。当您输入同步方法(或块)时,将启用锁定,当您退出该方法时,将禁用锁定。您可以调用各种其他未同步的方法,但它们仍将被锁定。但你的问题有两个不同的问题:
在java中,如果一个同步方法包含对非同步方法的调用,那么另一个方法能否同时访问该非同步方法?
对。其他方法可以访问非同步方法。
基本上我要问的是synchronized方法中的所有东西都有一个锁(包括对其他synchronized方法的调用)?
嗯,是的。对同步方法的其他调用被锁定。但是不同步的方法不会被锁定。
另外,请记住,如果方法
static
那么锁就在门上了Class
中的对象ClassLoader
.如果方法是示例方法,那么锁就在类的示例上。
在这两种情况下有两种不同的锁。
最后,当你处理
synchronized
示例方法,类的每个示例都被锁定。这意味着两个线程可以在同一个线程中synchronized
方法同时使用不同的示例。但是如果有两个线程尝试在synchronized
方法,其中一个将阻塞,直到另一个退出该方法。