初学者真的不理解
class X {
// 修饰非静态方法
synchronized void foo() {
// 临界区
}
// 修饰静态方法
synchronized static void bar() {
// 临界区
}
// 修饰代码块
Object obj = new Object();
void baz() {
synchronized(obj) {
// 临界区
}
}
}
我们都知道,第一种锁的是方法
第二种所的是类
第三种所的是对象
这三种锁它们的区别到底是什么呢?锁对象和锁类两个作用有啥区别啊,该怎么理解?
其实很好理解
静态方法是在类加载的时候被初始化到方法区,方法区是共享区域。也就意味着jvm运行期间,你所有的调用都是调用同一个方法。(所以这个锁全局有效)
而非静态修饰的方法是需要用对象实例调用,就是你对象创建一般是new指令创建新的对象。(所以这个锁只对此对象实例调用的方法生效,重新创建对象实例后不再生效)
对象的创建是通过在堆内存里分配空间完成的,方法帧中存在的局部变量表对应的其实也就是该对象实例在内存中的地址(简单理解)所以这个锁是判断对象实例是不是同一个地址如果是的话就互斥,不是的话就非互斥
下面是解释,你可以参考,希望对你有帮助。
**锁对象和锁类两个作用有啥区别__**在Java中,synchronized关键字可以修饰实例方法和静态方法。当修饰实例方法时,锁对象是实例对象本身;当修饰静态方法时,锁对象是类对象。
锁对象和锁类分别具有不同的作用和特点:(这个百度里面有好多的帖子,可以找一下)
因此,锁对象和锁类的主要区别在于锁对象用于对实例方法的同步控制,锁类用于对静态方法的同步控制。需要根据具体情况选择合适的锁方式。
其实都有一个共同点:都是对某个对象加锁。
1.修饰非静态方法 是对调用该方法的对象加锁。
X x = new X();
x.foo();
// 这里就是对x对象加锁,其他线程调用x.foo()时就会被卡住
2.修饰静态方法 是对该静态方法的类加锁,每个类在JVM中都有一个描述其结构的Class对象。
X x = new X();
x.bar();//这里对X.class对象加锁
x.foo();//其他线程调用这里会卡住,因为X.class已经在上一步被占用了
3.修饰代码块 是对自定义的对象加锁,灵活性比上面两种都要好
Object obj = new Object();
void baz() {
synchronized(obj) {
// 临界区
}
}
Object obj2 = new Object();
void baz2() {
synchronized(obj2) {
// 临界区
}
}
// 这两个方法加锁的对象不同,那么这两个方法的执行就是互不干扰的
不知道你这个问题是否已经解决, 如果还没有解决的话: