JUC-03 通过8锁现象了解锁

154 阅读3分钟
  • 锁分为锁对象和锁class
  • synchronized修饰方法锁的是对象,修饰静态方法锁的是class

场景一

/*
一个普通的synchronized多线程 先send还是先call
答案: send
原因: 两个synchronized锁的是同一个对象
*/
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        final Phone phone=new Phone();
        new Thread(()->{phone.send();}).start();
        TimeUnit.SECONDS.sleep(5);
        new Thread(()->{phone.call();}).start();
    }
}
class Phone{
    public synchronized void send(){
        System.out.println("send");
    }
    public synchronized void call(){
        System.out.println("call");
    }
}

场景二

/*
 在send延迟5秒的情况下,先send还是call
 答案 send
 原因:两个锁的是同一个对象,谁先拿到谁执行,sleep并不会释放锁
*/
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        final Phone phone=new Phone();
        new Thread(()->{phone.send();}).start();
        TimeUnit.SECONDS.sleep(5);
        new Thread(()->{phone.call();}).start();
    }
}
class Phone{
    public synchronized void send() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("send");
    }
    public synchronized void call(){
        System.out.println("call");
    }
}

场景三

/*
一个synchronized方法send,一个普通方法call,先执行send还是call
答案: 先执行send但是在sendsleep的时候call执行了,所以先输出call
原因: 普通方法call并不是同步方法,不受锁的影响,在send睡眠的时候执行。
*/
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        final Phone phone=new Phone();
        new Thread(()->{phone.send();}).start();
        TimeUnit.SECONDS.sleep(2);
        new Thread(()->{phone.call();}).start();
    }
}
class Phone{
    public synchronized void send()  {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send");
    }
    public  void call(){
        System.out.println("call");
    }

场景四

/*
两个synchronized方法send,call,两个对象phone,phone2 先执行send还是call
答案:先执行send但先输出call
原因:锁的是对象,两个不同的对象互不影响
*/
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        final Phone phone=new Phone();
        final Phone phone2=new Phone();
        new Thread(()->{phone.send();}).start();
        TimeUnit.SECONDS.sleep(2);
        new Thread(()->{phone2.call();}).start();
    }
}
class Phone{
    public synchronized void send()  {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send");
    }
    public synchronized void call(){
        System.out.println("call");
    }
}

场景五

/*
 两个静态方法被synchronized修饰,先执行哪个
 答案:先执行send
 原因:static关键字指明锁的是class,全局唯一
*/
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        final Phone phone=new Phone();
        new Thread(()->{phone.send();}).start();
        TimeUnit.SECONDS.sleep(2);
        new Thread(()->{phone.call();}).start();
    }
}
class Phone{
    public static synchronized void send()  {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send");
    }
    public static synchronized void call(){
        System.out.println("call");
    }
}

场景六

/*
 两个静态方法被synchronized修饰,两个对象,先执行哪个
 答案:先执行send
 原因:static关键字指明锁的是class,全局唯一,所以锁的是同一个
*/
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        final Phone phone=new Phone();
        final Phone phone2=new Phone();
        new Thread(()->{phone.send();}).start();
        TimeUnit.SECONDS.sleep(2);
        new Thread(()->{phone2.call();}).start();
    }
}
class Phone{
    public static synchronized void send()  {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send");
    }
    public static synchronized void call(){
        System.out.println("call");
    }
}

场景七

/*
被synchronized修饰的静态方法send和普通方法call,先输出哪个
答案: 先执行send,但先输出call
原因: 一个锁的对象,一个锁的class,互不影响
*/
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        final Phone phone=new Phone();
        new Thread(()->{phone.send();}).start();
        TimeUnit.SECONDS.sleep(2);
        new Thread(()->{phone.call();}).start();
    }
}
class Phone{
    public static synchronized void send()  {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send");
    }
    public synchronized void call(){
        System.out.println("call");
    }
}

场景八

/*
被synchronized修饰的静态方法send和普通方法call,先输出哪个
答案: 先执行send,但先输出call
原因: 一个锁的对象,一个锁的class,互不影响
*/
public class SynchronizedTest {
    public static void main(String[] args) throws InterruptedException {
        final Phone phone=new Phone();
         final Phone phone2=new Phone();
        new Thread(()->{phone.send();}).start();
        TimeUnit.SECONDS.sleep(2);
        new Thread(()->{phone2.call();}).start();
    }
}
class Phone{
    public static synchronized void send()  {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send");
    }
    public synchronized void call(){
        System.out.println("call");
    }
}