静态锁
如果锁定对象位于静态字段中,则该特定 Class 的所有实例都将共享该锁。这意味着如果从该类创建的一个对象正在访问该static 锁,则从该类创建的另一个对象无法访问该锁。
非静态锁
如果类有一个非静态的锁,那么每个实例都有自己的锁,所以只有在同一个对象上的方法调用才会相互锁定。
以使用静态锁对象为例:
- 线程 1 调用
obj01.doSomething()
- 线程 2 调用
obj01.doSomething(),必须等待线程 1 完成
- 线程 3 调用
obj02.doSomething(),还必须等待线程 1(可能还有 2)完成。
当您使用非静态锁对象时:
- 线程 1 调用
obj01.doSomething()
- 线程 2 调用
obj01.doSomething(),必须等待线程 1 完成
- 线程 3 调用
obj02.doSomething(),它可以继续,不介意线程 1 和 2,因为这是一个新对象,它不依赖于类。
非静态锁基本上是对象级锁。静态锁是类级别的锁
对象级别锁定
Java 中的每个对象都有一个唯一的锁。如果线程想要对给定对象执行同步方法,首先它必须获得该对象的锁。一旦线程获得锁,就可以在该对象上执行任何同步方法。一旦方法执行完成,线程就会自动释放锁。
public class Example implements Runnable {
@Override
public void run() {
objectLock();
}
public void objectLock() {
System.out.println(Thread.currentThread().getName());
synchronized(this) {
System.out.println("Synchronized block " + Thread.currentThread().getName());
System.out.println("Synchronized block " + Thread.currentThread().getName() + " end");
}
}
public static void main(String[] args) {
Example test1 = new Example();
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test1);
Example test2 = new Example();
Thread t3 = new Thread(test2);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
输出将是,
t1
t3
Synchronized block t1
t2
Synchronized block t1 end
Synchronized block t3
Synchronized block t2
Synchronized block t3 end
Synchronized block t2 end
类级别锁
Java 中的每个类都有一个唯一的锁,它只不过是一个类级别的锁。如果一个线程想要执行一个静态同步方法,那么该线程需要一个类级别的锁。一旦线程获得了类级别的锁,就可以执行该类的任何静态同步方法。一旦方法执行完成,线程就会自动释放锁。
public class Example implements Runnable {
@Override
public void run() {
classLock();
}
public static void classLock() {
System.out.println(Thread.currentThread().getName());
synchronized(Example.class) {
System.out.println("Synchronized block " + Thread.currentThread().getName());
System.out.println("Synchronized block " + Thread.currentThread().getName() + " end");
}
}
public static void main(String[] args) {
Example test1 = new Example();
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test1);
Example test2 = new Example();
Thread t3 = new Thread(test2);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
输出将如下所示,
t1
t3
t2
Synchronized block t1
Synchronized block t1 end
Synchronized block t2
Synchronized block t2 end
Synchronized block t3
Synchronized block t3 end
当前情景
在这里,您有两种方法,如果使用一个锁访问一个方法,而另一个使用另一个锁,则通过您的实现,您可以让两个对象使用彼此的方法,但不能使用相同的方法。
obj01.method01();
obj02.method02();
这是可能的,但不是这个
obj01.method01();
obj02.method01();
你 obj02 必须等到 obj01 完成该方法。