8种锁现象

导读:本篇文章讲解 8种锁现象,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

8锁现象

synchronized锁定的到底是什么?

https://www.zhihu.com/question/57794716

如何判断锁的是谁;永远知道他是什么锁,锁到底锁的是谁。
深刻理解我们的锁

1:标准情况下,两个方法,同时加锁,一个对象;
2: 给延迟时间,看哪一个先执行

package com.baidu.Lock8;

/**
 * 关于所得8个问题=
 * 1:标准情况下,答:1、发短息 2、打电话
 *      1 结果:多个线程使用同一个对象,多个线程就是使用一把锁,先调用的先执行!
 *
 * 2:给sendSms延迟4 秒执行,答:1、发短息 2、打电话
 *      2 结果:多个线程使用同一个对象,多个线程就是使用一把锁,先调用的先执行,即使在某方法中设置了阻塞。
 *
 *
 */

import java.util.concurrent.TimeUnit;

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{

    //synchronized  锁的对象是 方法的调用者。
    //两个方法,用的是同一个锁,谁先拿到是谁执行
    public synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

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

3:添加一个普通的对象;(不加锁)
4:两个对象,两个同步方法,谁先执行;

package com.baidu.Lock8;

/**
 * 3:增加一个普通的方法(没有加锁,): 答:1、hello 2、发短信;
 *      结果:多个线程,有的线程有锁,有的线程没锁,两者之间不存在竞争同一把锁的情况,先后执行顺序是随机的。
 *
 * 4:两个对象,两个同步方法,执行? 答:1、打电话  2、发短息
 *      结果:1、被 synchronized 修饰的方法,锁的对象是方法的调用者;
 *            2、调用者不同,它们之间用的不是同一个锁,相互之间没有关系
 */

import java.util.concurrent.TimeUnit;

public class Test2 {

    public static void main(String[] args) {

        //两个对象,两个调用者,两把锁
        Phone2 phone1 = new Phone2();
        Phone2 phone2 = new Phone2();

//        new Thread(()->{
//            phone1.hello();
//        }).start();

        new Thread(()->{
            phone1.sendSms();
        },"A").start();

        //休息一秒;
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

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


    }
}

class Phone2{

    //synchronized  锁的对象是 方法的调用者。
    //两个方法,用的是同一个锁,谁先拿到是谁执行
    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");
    }
}

5:添加两个静态的同步方法,只有一个对象
6:两个对象,添加两个静态的同步方法。

package com.baidu.Lock8;

/**
 * 5:增加两个静态的同步方法;只有一个对象:  答:1、发短息  2、打电话
 *  * 被 synchronized 和 static 同时修饰的方法,锁的对象是类的 class 对象,是唯一的一把锁。线程之间是顺序执行。
 *  * 锁Class和锁对象的区别:
 *  *
 *  * 1、Class 锁 ,类模版,只有一个;
 *  * 2、对象锁 , 通过类模板可以new 多个对象。
 *
 *
 *
 * 6:增加两个静态的同步方法;两个对象  答:1、发短息  2、打电话
 *  * 被 synchronized 修饰 和 static 修饰的方法,锁的对象是类的 class 对象,是唯一的一把锁。
 *  * Class锁是唯一的,所以多个对象使用的也是同一个Class锁。
 *
 *
 */

import java.util.concurrent.TimeUnit;

public class Test3  {

    public static void main(String[] args) {

        //两个对象的Class类模板只有一个,static ,所得是Class对象;
        Phone3 phone1 = new Phone3();
        Phone3 phone2 = new Phone3();


        new Thread(()->{
            phone1.sendSms();
        },"A").start();

        //休息一秒;
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

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

//
class Phone3{

    //synchronized  锁的对象是 方法的调用者。
    //static  静态方法;
    //类一加载就有了,所得是 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("打电话");

    }

}

7:一个静态的同步方法,一个普通的同步方法。一个对象;
8:一个静态的同步方法,一个普通的同步方法。两个对象;

package com.baidu.Lock8;

/**
 * 7: 一个静态的同步方法 ,一个普通的同步方法;一个对象;答:1、打电话  2、发信息
 *  * 被 synchronized和static修饰的方法,锁的对象是类的class对象!唯一的同一把锁;
 *  * 只被synchronized修饰的方法,是普通锁(如对象锁),不是Class锁,所以进程之间执行顺序互不干扰。
 *
 *
 *
 *
 * 8: 一个静态的同步方法 ,一个普通的同步方法;两个对象;答:1、打电话  2、发信息
 *  * 被 synchronized和static修饰的方法,锁的对象是类的class对象!唯一的同一把锁;
 *  * 只被synchronized修饰的方法,是普通锁(如对象锁),不是Class锁,所以进程之间执行顺序互不干扰。
 *
 */

import java.util.concurrent.TimeUnit;

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{

    //静态的同步方法
    //类一加载就有了,所得是 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("打电话");

    }

}

深入理解:

https://blog.csdn.net/makyan/article/details/104524725

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/71877.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!