Java 多个同步关键字如何在一个类中工作?
假设一个线程在一个同步块中执行。另一个线程能否获得其他同步块上的锁Java 多个同步关键字如何在一个类中工作?,java,thread-safety,synchronize,Java,Thread Safety,Synchronize,假设一个线程在一个同步块中执行。另一个线程能否获得其他同步块上的锁 如果在同步块内对非同步方法进行方法调用,会发生什么情况?该方法是线程安全的吗? 如果我们尝试从同步实例方法访问静态变量会怎么样??每次,访问每个实例中的同步块的每个线程都会尝试修改静态变量。不是吗?在这种情况下,我们如何保证线程安全 另一个线程能否获得其他同步块上的锁 不可以,一次只能运行一个同步方法。对另一个同步方法的调用必须等到第一个方法完成。以下章节对此进行了描述: …同一对象上的两个同步方法调用不可能交错。当一个线程为一
如果在同步块内对非同步方法进行方法调用,会发生什么情况?该方法是线程安全的吗?
如果我们尝试从同步实例方法访问静态变量会怎么样??每次,访问每个实例中的同步块的每个线程都会尝试修改静态变量。不是吗?在这种情况下,我们如何保证线程安全 另一个线程能否获得其他同步块上的锁 不可以,一次只能运行一个同步方法。对另一个同步方法的调用必须等到第一个方法完成。以下章节对此进行了描述: …同一对象上的两个同步方法调用不可能交错。当一个线程为一个对象执行同步方法时,调用同一对象块的同步方法的所有其他线程(暂停执行),直到第一个线程对该对象执行完毕 如果在同步块内对非同步方法进行方法调用,会发生什么情况?该方法是线程安全的吗 如果只从属于此对象的同步方法调用非同步方法,则可以认为它是线程安全的,因为一次只有一个线程可以执行一个调用(同步)方法 请注意,正如@Ordous在下面指出的,静态同步方法锁定在类上,而非静态同步方法锁定在实例上。因此,非静态方法可以与属于所讨论类的静态方法交错
args
synchronized
关键字锁定了一段代码
同步的关键字做什么?
它锁定对象而不是方法。因此,如果您将synchronized
关键字放在方法前面,那么它将锁定此
对象。因此,任何其他线程都不能执行具有synchronized
关键字的任何其他方法
这与静态
和非静态
方法不同,因为当同步静态方法时,它不会锁定此
,但会锁定默认类对象,即A.class
对象。如果您有另一个静态同步方法,那么任何其他线程都不会执行该方法
在sync blocks
的情况下,它将获得对象上的锁,该对象在您的情况下作为参数传递,它是args
。
因此,如果在其他任何地方有另一个
同步块
在同一对象上获取锁,那么它将不得不等待,直到第一个线程完成并释放锁。同步代码上始终存在锁。要访问代码线程,必须获取密钥、解锁、运行并返回密钥
存在一个对象级锁,该锁是整个对象的锁,而不是某个方法或块的锁。因此,即使单个实例上有多个同步块或方法,也只有一个线程可以获取密钥并访问同步代码。然后它将把密钥交还给对象,然后其他线程可以继续获取密钥并访问同步代码
如果您想知道声明为syncrhonized的静态方法会发生什么情况(因为它们没有与之关联的对象/实例),那么在这种情况下,类本身也始终存在一个锁。要访问类的任何同步静态
部分,线程必须从类获取密钥以解锁锁
注意:-我提到的锁和键只是为了帮助理解,没有方法或方法来访问键或任何由JVM内部维护的东西。首先,一个类中可以有多个同步方法。这是通过以下方式实现的:
- 将方法声明为已同步
- 同步方法
非同步方法不是这样的,它们可以并发执行。不,该方法将根据需要执行,不一定分别执行。但是一个对象有一个锁。那么,为什么另一个线程会获得锁,因为它已经被第一个线程占用了呢?哦,糟糕,很好。那里有一个小的大脑屁。编辑。除了一个s同一对象的static和非static方法。它们可以交错(熟悉Java的人会知道它们是实例和类方法,因此具有不同的锁,但如果给出OPs问题,这将是一个有用的注释)在这种情况下,它的“args”更清楚地说,如果我们尝试从同步实例方法访问静态变量,每次每个线程访问e中的同步块,会怎么样
package anonymous;
public class A {
public static int counter=0;
public static void main(String[] args) {
synchronized (args) {
//some logic
}
synchronized (args) {
//some logic
}
}
}