首页 > 其他 > 详细

synchronize锁现象

时间:2021-02-26 23:32:47      阅读:30      评论:0      收藏:0      [点我收藏+]

资源类:

class Phone{
    public synchronized void sendEmail() throws Exception{
        System.out.println("-----------Email");
    }
    public synchronized void sendSMS() throws Exception{
        System.out.println("-----------SMS");
    }
}

 

线程操作资源类

public class LockDemo {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(()->{
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"A").start();
        Thread.sleep(100); //为了保证先A再B
        new Thread(()->{
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}

 

问题:

  标准访问,请问先打印Email还是SMS

    先打印Email,再打印SMS

 

   邮件方法暂停4s,请问先打印Email还是SMS

class Phone{
    public synchronized void sendEmail() throws Exception{
        Thread.sleep(4000);
        System.out.println("-----------Email");
    }
    public synchronized void sendSMS() throws Exception{
        System.out.println("-----------SMS");
    }
}

    先打印Email,再打印SMS

 

  新增一个普通方法hello,请问先打印hello还是email

class Phone{
    public synchronized void sendEmail() throws Exception{
        Thread.sleep(4000);
        System.out.println("-----------Email");
    }
    public synchronized void sendSMS() throws Exception{
        System.out.println("-----------SMS");
    }

    public void sayHello() throws Exception{
        System.out.println("-----------Hello");
    }
}

 

public class LockDemo {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(()->{
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"A").start();
        Thread.sleep(100);
        new Thread(()->{
            try {
                phone.sayHello();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}

    先打印Hello,隔4s后再打印Email

 

  两部手机,先打印Email,还是SMS(Email内休息4s)

public class LockDemo {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(()->{
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"A").start();
        Thread.sleep(100);
        new Thread(()->{
            try {
                phone2.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}

    先打印SMS,隔4s再打印Email

 

  两个静态同步方法,同一个手机,先打印Email,还是SMS

class Phone{
    public static synchronized void sendEmail() throws Exception{
        Thread.sleep(4000);
        System.out.println("-----------Email");
    }
    public static synchronized void sendSMS() throws Exception{
        System.out.println("-----------SMS");
    }
}

    先打印Email,再打印SMS

 

  两个静态同步方法,2部手机,先打印Email,还是SMS

public class LockDemo {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(()->{
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"A").start();
        Thread.sleep(100);
        new Thread(()->{
            try {
                phone2.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}

    先打印Email,再打印SMS

 

  一个静态同步方法,一个普通同步方法,一个手机,先打印Email还是SMS

class Phone{
    public static synchronized void sendEmail() throws Exception{
        Thread.sleep(4000);
        System.out.println("-----------Email");
    }

    public synchronized void sendSMS() throws Exception{
        System.out.println("-----------SMS");
    }
}

 

public class LockDemo {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(()->{
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"A").start();
        Thread.sleep(100);
        new Thread(()->{
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}

    先打印SMS,隔四秒再打印Email

 

  一个静态同步方法,一个普通同步方法,2个手机,先打印Email还是SMS

public class LockDemo {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(()->{
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"A").start();
        Thread.sleep(100);
        new Thread(()->{
            try {
                phone2.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}

    先打印SMS,隔四秒再打印Email

 

锁结论:

  对于非静态同步方法

    所有的非静态同步方法都是用的同一把锁 ==> 实例对象本身

    一个对象里面如果有多个synchronized方法,某一时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一的一个线程去访问这些synchronized方法

    如果一个实例对象的非静态同步方法获取锁后,该实例对象的其它非静态同步方法必须等待 当前获取锁的方法 释放锁后才能获取锁

    对于多个线程去访问同一类下不同实例对象的非静态同步方法时,不需要去等待锁被释放,因为此时的锁并不是同一个

 

  对于静态同步方法

    所有的静态同步方法,锁 ==> 类的class (发射机制)

    一个静态同步方法获取锁后,其他的静态同步方法必须等待该方法释放锁后才能获取锁,此时不需要关心是否是同一个实例对象,只要它们属于这个类即可

    但是非静态同步方法的锁和静态同步方法的锁是两个不同的对象,这两种方法之间不会存在竞争关系

 

  对于同步代码块

    所有同步代码块synchronized(){},锁 ==>  ()中配置的对象

    当一个线程访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁

 

synchronize锁现象

原文:https://www.cnblogs.com/pikachu511/p/14452263.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!