1.说明
Java中的锁按等级分可以分为对象锁、方法锁、类锁。
对象锁和方法锁其实是同一个东西
java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的
2示例
2.1示例1
package com.jinsenianhua.common.utils.contractPoi; /** * @Classname Thread1 * @Description TODO * @Date 2021/7/26 0026 下午 3:54 * @Created by jcc */ public class Test0 { private int num = 0; public synchronized void printNum(String arg){ if (arg.equals("a")){ num = 100; System.out.println("num value is "+ num); try { new Thread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else { num = 200; System.out.println("num value is "+ num); } System.out.println("tag = " + arg + " num = " + num); } public static void main(String[] args) { final Test0 t1 = new Test0(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { t1.printNum("a"); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { t1.printNum("b"); } }); thread1.start(); thread2.start(); } }
打印结果:
num value is 100
tag = a num = 100
num value is 200
tag = b num = 200
上面这个锁在普通方法上,是方法锁。可以看到,锁生效了。这个锁是对象级别的,我创建了一个对象,他们的锁对象是不一样了,所以锁生效。
2.2示例2
package com.jinsenianhua.common.utils.contractPoi; /** * @Classname Thread1 * @Description TODO * @Date 2021/7/26 0026 下午 3:54 * @Created by jcc */ public class Test { private int num = 0; public synchronized void printNum(String arg){ if (arg.equals("a")){ num = 100; System.out.println("num value is "+ num); try { new Thread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else { num = 200; System.out.println("num value is "+ num); } System.out.println("tag = " + arg + " num = " + num); } public static void main(String[] args) { final Test t1 = new Test(); final Test t2 = new Test(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { t1.printNum("a"); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { t2.printNum("b"); } }); thread1.start(); thread2.start(); } }
打印结果:
num value is 200
num value is 100
tag = b num = 200
tag = a num = 100
上面这个锁在普通方法上,是方法锁。可以看到,锁是没有生效的。这里和上面的区别是,创建的是两个对象。因为这个锁是对象级别的,我创建了两个对象,他们的锁对象是不一样了,所以锁没有生效。
2.3示例3
package com.jinsenianhua.common.utils.contractPoi; /** * @Classname Test2 * @Description TODO * @Date 2021/7/26 0026 下午 4:02 * @Created by jcc */ public class Test2 { private static int num = 0; public static synchronized void printNum(String arg){ if (arg.equals("a")){ num = 100; System.out.println("num value is "+ num); try { new Thread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else { num = 200; System.out.println("num value is "+ num); } System.out.println("tag = " + arg + " num = " + num); } public static void main(String[] args) { final Test2 t1 = new Test2(); final Test2 t2 = new Test2(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { t1.printNum("a"); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { t2.printNum("b"); } }); thread1.start(); thread2.start(); } }
打印结果:
num value is 100
tag = a num = 100
num value is 200
tag = b num = 200
上面这个锁在静态方法上,是类锁。可以看到,锁生效了。因为这个锁是类级别的,所有对象的锁是同一个,我创建了两个对象,但是他们的锁对象是同一个,所以锁生效。
package com.jinsenianhua.common.utils.contractPoi;
/**
* @Classname Thread1
* @Description TODO
* @Date 2021/7/26 0026 下午 3:54
* @Created by jcc
*/
public class Test {
private int num = 0;
public synchronized void printNum(String arg){
if (arg.equals("a")){
num = 100;
System.out.println("num value is "+ num);
try {
new Thread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
num = 200;
System.out.println("num value is "+ num);
}
System.out.println("tag = " + arg + " num = " + num);
}
public static void main(String[] args) {
final Test t1 = new Test();
final Test t2 = new Test();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
t1.printNum("a");
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
t2.printNum("b");
}
});
thread1.start();
thread2.start();
}
}