一、对象锁
1.解释
对象锁,顾名思义锁的是对象实例,但程序中同一个类可以有多个实例化对象,所以对象锁只能锁住同一个实例化对象,再两个或多个实例化对象之间不起作用。
2.使用方法
(1) 锁住实体里的非静态变量
synchronized(变量名)
(2)锁住 this 对象
synchronized(this)
(3)直接锁非静态方法
直接加在方法返回类型前。
public synchronized void fun(){}
3.更详细的了解对象锁(一定要看,初学时遇到下面的情况很容易迷)
import java.util.concurrent.TimeUnit;
public class DeadLockDemo {
public static void main(String[] args) {
MyThread myThread1 = new MyThread("A","B");
MyThread myThread2 = new MyThread("B","A");
new Thread(myThread1,"T1").start();
new Thread(myThread2,"T2").start();
}
}
class MyThread implements Runnable{
private String lockA;
private String lockB;
public MyThread(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
/**
* 锁的是String对象,所以锁的其实是常量池中的变量
* 比如lockA此时我们传入的是 “A” ,那么synchronized其实锁的就是常量池中的 “A”
* 当synchronized锁住 “A” 时我们在传入 “C”,是可以进入synchronized的
* 因为从地址上来看,lockA中存放“A”和lockA中存放“C”已经是两个对象了
*/
synchronized (lockA){
System.out.println(Thread.currentThread().getName() + "lock" + lockA + "=>get" + lockB);
try {
TimeUnit.SECONDS.sleep(2);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (lockB){
System.out.println(Thread.currentThread().getName() + "lock" + lockB + "=>get" + lockA);
}
}
}
}
二、类锁
1.解释
类锁,顾名思义锁的是类,而在java中我们的类加载是唯一的,即在JVM中类是唯一的,所以加了类锁,不管我们实例化多少对象都还是会被锁住。
2.使用方法
(1)锁住类中的静态变量
private static Object Variable = new Object();
synchronized(Variable)
(2)直接在静态方法上加 synchronized
public static synchronized void fun(){}
(3)锁住 xxx.class
synchronized(Class.class)