package cn.yishijie;
import java.util.concurrent.TimeUnit;
public class EightLockQuestion {
public static void main(String[] args) throws Exception{
//question01();// 结果:AAA BBB
//question2();// 结果:CCC AAA
//question3();// 结果:BBB AAA
// question4();// 结果:DDD EEE
// question5();// 结果:DDD EEE
// question6();// 结果:BBB DDD
question7();// 结果:BBB DDD
}
private static void question7() throws InterruptedException {
// 静态方法的锁是Class对象,类一加载就有了,因为D线程调用的锁都是唯一的Class对象
// D线程拿到了锁Class,睡了6秒,但是线程B是实例方法,所以锁是source1这个实例,他们的
// 锁不同,所以在D线程睡的时间段,时间片轮到线程B,然后线程B打印结果,再打印线程D
Source source0 = new Source();
Source source1 = new Source();
new Thread(()->{
source0.printD();
},"D").start();
TimeUnit.SECONDS.sleep(3); // 保证先让D线程跑起来
new Thread(()->{
source1.printB();
},"B").start();
}
private static void question6() throws InterruptedException {
// 静态方法的锁是Class对象,类一加载就有了,因为D线程调用的锁都是唯一的Class对象
// D线程拿到了锁Class,睡了6秒,但是线程B是实例方法,所以锁是source0这个实例,他们的
// 锁不同,所以在D线程睡的时间段,时间片轮到线程B,然后线程B打印结果。
Source source0 = new Source();
new Thread(()->{
source0.printD();
},"D").start();
TimeUnit.SECONDS.sleep(3); // 保证先让D线程跑起来
new Thread(()->{
source0.printB();
},"B").start();
}
private static void question5() throws InterruptedException {
// 静态方法的锁是Class对象,类一加载就有了,因为source0 source1 调用的锁都是唯一的Class对象
// D线程拿到了锁,睡了6秒,但是锁
// 还没有释放,所以E处于阻塞状态,因此先打印DDD 然后 EEE
Source source0 = new Source();
Source source1 = new Source();
new Thread(()->{
source0.printD();
},"D").start();
TimeUnit.SECONDS.sleep(3); // 保证先让D线程跑起来
new Thread(()->{
source1.printE();
},"E").start();
}
private static void question4() throws InterruptedException {
// 静态方法的锁是Class对象,类一加载就有了,因为D线程拿到了锁,睡了6秒,但是锁
// 还没有释放,所以E处于阻塞状态,因此先打印DDD 然后 EEE
Source source0 = new Source();
new Thread(()->{
source0.printD();
},"D").start();
TimeUnit.SECONDS.sleep(3); // 保证先让D线程跑起来
new Thread(()->{
source0.printE();
},"E").start();
}
private static void question3() throws InterruptedException {
// source0和source1两个对象,相对于两个锁,不互相影响
// 因为A线程睡了6秒,同时两个线程的锁不同,所以先打BB 然后 AA
Source source0 = new Source();
Source source1 = new Source();
new Thread(()->{
source0.printA();
},"A").start();
TimeUnit.SECONDS.sleep(3); // 保证先让A线程跑起来
new Thread(()->{
source1.printB();
},"B").start();
}
private static void question2() throws InterruptedException {
// 第一个锁问题,非静态synchronized方法的锁是调用该方法的对象
// 对于C线程,由于没有锁,所以在A线程睡眠的时候,时间片,轮到C
// 的时候,C就执行打印了
Source source = new Source();
new Thread(()->{
source.printA();
},"A").start();
TimeUnit.SECONDS.sleep(3); // 保证先让A线程跑起来
new Thread(()->{
source.printC();
},"C").start();
}
private static void question01() throws InterruptedException {
// 第一个锁问题,非静态synchronized方法的锁是调用该方法的对象
// 对于A线程,虽然是睡了6秒(或者不睡),但是他的锁是source,没有释放,所以
// B线程没有拿到锁,处于阻塞状态,只有当A执行完,释放锁,B才能执行
Source source = new Source();
new Thread(()->{
source.printA();
},"A").start();
TimeUnit.SECONDS.sleep(3); // 保证先让A线程跑起来
new Thread(()->{
source.printB();
},"B").start();
}
}
class Source {
public synchronized void printA(){
try {
TimeUnit.SECONDS.sleep(6);
System.out.println("AAA");
}catch (Exception e){
}
}
public synchronized void printB(){
System.out.println("BBB");
}
public void printC(){
System.out.println("CCC");
}
public static synchronized void printD(){
try {
TimeUnit.SECONDS.sleep(6);
System.out.println("DDD");
}catch (Exception e){
}
}
public static synchronized void printE(){
System.out.println("EEE");
}
}