在 Java 中,在单个对象和线程中使用 synchronized 关键字。
我可以调用一个调用同步方法的非同步方法的同步方法,而不会阻塞最终同步方法以完成第一个同步方法吗?
在 Java 中,在单个对象和线程中使用 synchronized 关键字。
我可以调用一个调用同步方法的非同步方法的同步方法,而不会阻塞最终同步方法以完成第一个同步方法吗?
使用单个对象和单个线程,没有问题。
您唯一的线程能够获取所有锁,并且由于可重入,它可以多次获取它们。
即使我们添加另一个线程,它也会工作(使用一个对象)。一个线程将获取第一个锁,阻塞第二个线程,然后继续正常执行。
对于多个线程和多个对象,答案是“这取决于代码的编写方式”。
无论是否同步,您的代码始终可以调用方法。一个更好的问题是,当您的代码调用它时会发生什么。
一个如下所示的同步方法:
synchronized void foobar() {
doSomething();
}
实际上只是写这个的一种简写方式:
void foobar() {
synchronized(this) {
doSomething();
}
}
所以任何关于调用同步方法的问题实际上都是关于执行同步块的问题。当您的代码进入synchronized(this) {...}
.
1)如果this
对象没有加锁,则以调用线程的名义加锁,线程将执行块中的语句,完成后解锁。
2)如果this
对象已经被调用线程锁定,那么线程将简单地执行块中的语句。
3) 如果this
对象被其他线程锁定,则调用线程将等待,直到其他线程解锁它,然后它会像情况(1)一样继续。
您遇到麻烦的唯一方法是您的代码尝试锁定两个不同的锁。然后,如果您的设计没有经过深思熟虑,两个或更多线程可能会死锁,这是您可以在其他地方阅读的内容。
如果一个类同时具有同步和非同步方法,则多个线程仍然可以访问该类的非同步方法。如果您的方法不访问您要保护的数据,则不需要同步他们。在某些情况下,同步可能会导致命中(如果使用不当,甚至会出现死锁)