多线程之 八锁。

package lock8;

import java.util.concurrent.TimeUnit;

/**
 * 8锁 就是关于锁的8个问题
 * 1.标准情况下,两个线程先打印 发短信还是打电话? ->发短信 原因 A先执行 A先拿到锁,
 */
public class Test1 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}

class Phone{
    public synchronized  void sendSms(){
        System.out.println("发短信");
    }

    public synchronized  void call(){
        System.out.println("打电话");
    }
}
View Code
package lock8;

import java.util.concurrent.TimeUnit;

/**
 * 答案 发短信 原因: synchronized 锁住了 Phone2实例化的对象, 只有当短信执行完以后 锁才会被释放
 */
public class Test2  {
    public static void main(String[] args) {
        Phone2 phone = new Phone2();
        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}

class Phone2{
    public synchronized  void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized  void call(){
        System.out.println("打电话");
    }
}
View Code
package lock8;

import java.util.concurrent.TimeUnit;

/**
 * 增加了一个普通方法后,先执行 hello 还是发短信。 执行的是 hello 原因,hello没有锁,不是同步方法,不受锁的影响
 */
public class Test3  {
    public static void main(String[] args) {
        Phone3 phone = new Phone3();
        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.hello();
        },"B").start();
    }
}

class Phone3{
    public synchronized  void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized  void call(){
        System.out.println("打电话");
    }

    //这里没有锁,不是同步方法,不受锁的影响
    public void hello(){
        System.out.println("hello");
    }
}
View Code
package lock8;

import java.util.concurrent.TimeUnit;

/**
 * 执行结果:打电话 原因:一个对象 只有一把锁。 phone1的锁 不影响phone2的锁 。
 */
public class Test4  {
    public static void main(String[] args) {
        Phone4 phone1 = new Phone4();
        Phone4 phone2 = new Phone4();
        new Thread(()->{
            phone1.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}

class Phone4{
    public synchronized  void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized  void call(){
        System.out.println("打电话");
    }
}
View Code
package lock8;

import java.util.concurrent.TimeUnit;

/**
 * 执行结果:发短信  原因 :锁的是phone5这个class。
 */
public class Test5  {
    public static void main(String[] args) {
        Phone5 phone = new Phone5();
        new Thread(()->{
            phone.sendSms();
        },"A").start();


        new Thread(()->{
            phone.call();
        },"B").start();
    }
}

class Phone5{

    //static 静态方法 类一加载就有了,锁的是class
    //Class<Phone5> phone5Class = Phone5.class;
    public static synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }


    public static  synchronized void call(){

        System.out.println("打电话");
    }
}
View Code
package lock8;

import java.util.concurrent.TimeUnit;

/**
 * 执行结果:发短信  原因 :锁的是phone5这个class。
 */
public class Test6  {
    public static void main(String[] args) {
        //两个对象的Class类模板 只有一个,static,锁的是class。
        //疑问,可以看到static修饰的只是Phone6类里面的具体的方法。 跟Class类模板有关系吗?
        Phone6 phone1 = new Phone6();
        Phone6 phone2 = new Phone6();
        new Thread(()->{
            phone1.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}

class Phone6{

    //static 静态方法 类一加载就有了,锁的是class
    //Class<Phone5> phone5Class = Phone5.class;
    public   static  synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }


    public  static synchronized   void call(){
        System.out.println("打电话");
    }
}
View Code
package lock8;

import java.util.concurrent.TimeUnit;

/**
 * 执行结果:打电话  原因 :锁的是phone5这个class。
 */
public class Test7  {
    public static void main(String[] args) {
        //两个对象的Class类模板 只有一个,static,锁的是class。
        //疑问,可以看到static修饰的只是Phone6类里面的具体的方法。 跟Class类模板有关系吗?
        Phone7 phone = new Phone7();
        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}

class Phone7{

    //static 静态方法 类一加载就有了,锁的是class
    //static 修饰的方法 锁的是class模板。 一个类里 所有的方法 被static修饰过以后  锁的都是class模板
    public   static  synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    //普通的同步方法
    public   synchronized   void call(){
        System.out.println("打电话");
    }
}
View Code
package lock8;

import java.util.concurrent.TimeUnit;

/**
 * 执行结果:打电话 原因 :static 修饰的方法 锁的是class模板。 一个类里 所有的方法 被static修饰过以后  锁的都是class模板
 */
public class Test8  {
    public static void main(String[] args) {
        //两个对象的Class类模板 只有一个,static,锁的是class。
        //疑问,可以看到static修饰的只是Phone6类里面的具体的方法。 跟Class类模板有关系吗?
        Phone8 phone1 = new Phone8();
        Phone8 phone2 = new Phone8();
        new Thread(()->{
            phone1.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}

class Phone8{

    //static 静态方法 类一加载就有了,锁的是class
    //static 修饰的方法 锁的是class模板。 一个类里 所有的方法 被static修饰过以后  锁的都是class模板
    public   static  synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    //普通的同步方法
    public   synchronized   void call(){
        System.out.println("打电话");
    }
}
View Code

总结: 什么是锁 , 永远记住一句话, synchronized 锁  锁的永远都是对象,       一个对象只可能有一把锁。  

如果一个类某一个方法  用static+synchronized  修饰了。 那么 该类 所有同样被 static+synchronized 修饰的方法 锁的都是类的模板。 

synchronized
posted @ 2021-11-11 16:36  斯拉克  阅读(26)  评论(0编辑  收藏  举报