为了账号安全,请及时绑定邮箱和手机立即绑定

static和synchronized

标签:
Java

static和synchronized

2个线程模拟手机发邮件和发短信功能

八锁

  • 标准访问 2个线程 一部手机资源类
  • 发邮件睡眠4
  • 新增sayHello方法
  • 两部手机资源类
  • 2个静态同步方法 一部手机
  • 2个静态同步方法 两部部手机
  • 1个静态同步方法 一个普通同步方法 一部手机
  • 1个静态同步方法 一个普通同步方法 两部部手机

场景一

标准访问 2个线程 一部手机资源类

package com.zbiti.juc;

import java.util.concurrent.TimeUnit;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        
        new Thread(() -> {
            phone.sendEmail();
        }, "AA").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.sendSMS();
        }, "BB").start();
    }
}

//手机资源类,带发邮件、发短信功能
class Phone {
    //发邮件
     synchronized void sendEmail() {
        System.out.println("sendEmail----->");
    }

    //发短信
    synchronized void sendSMS() {
        System.out.println("sendSMS------->");
    }


}

结果

1574948896560

场景二

发邮件睡眠4

package com.zbiti.juc;

import java.util.concurrent.TimeUnit;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "AA").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.sendSMS();
        }, "BB").start();
    }
}

//手机资源类,带发邮件、发短信功能
class Phone {
    //发邮件
     synchronized void sendEmail() {
         try {
             TimeUnit.SECONDS.sleep(4);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         
         System.out.println("sendEmail----->");
    }

    //发短信
    synchronized void sendSMS() {
        System.out.println("sendSMS------->");
    }
}

结果

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

1574948896560

场景三

新增sayHello方法

package com.zbiti.juc;

import java.util.concurrent.TimeUnit;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "AA").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.sayHello();
        }, "BB").start();
    }
}

//手机资源类,带发邮件、发短信功能
class Phone {
    //发邮件
     synchronized void sendEmail() {
         try {
             TimeUnit.SECONDS.sleep(4);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }

         System.out.println("sendEmail----->");
    }

    //发短信
    synchronized void sendSMS() {
        System.out.println("sendSMS------->");
    }

    void sayHello(){
        System.out.println("sayHello------>");
    }
}

结果

加个普通方法后发现和同步方法无关

1574949724372

场景四

两部手机资源类

package com.zbiti.juc;

import java.util.concurrent.TimeUnit;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "AA").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone2.sendSMS();
        }, "BB").start();
    }
}

//手机资源类,带发邮件、发短信功能
class Phone {
    //发邮件
     synchronized void sendEmail() {
         try {
             TimeUnit.SECONDS.sleep(4);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }

         System.out.println("sendEmail----->");
    }

    //发短信
    synchronized void sendSMS() {
        System.out.println("sendSMS------->");
    }

    void sayHello(){
        System.out.println("sayHello------>");
    }


}

结果

换成两个对象后,不是同一把锁,情况立刻发生了变化,所有的非静态同步方法用的都是同一把锁,即实例对象本身

1574949828714

场景五

2个静态同步方法 一部手机

package com.zbiti.juc;

import java.util.concurrent.TimeUnit;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "AA").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.sendSMS();
//            phone2.sendSMS();
        }, "BB").start();
    }
}

//手机资源类,带发邮件、发短信功能
class Phone {
    //发邮件
    static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("sendEmail----->");
    }

    //发短信
    static synchronized void sendSMS() {
        System.out.println("sendSMS------->");
    }

    void sayHello() {
        System.out.println("sayHello------>");
    }
}

结果

synchronized实现同步的基础,java中的每一个对象都可以作为锁,具体表现以下3种形式

  • 对于普通同步方法,锁是当前实例对象
  • 对于同步方法块,锁是synchronized括号里配置的对象
  • 对于静态同步方法,锁是当前类的Class对象

1574948896560

场景六

2个静态同步方法 两部部手机

package com.zbiti.juc;

import java.util.concurrent.TimeUnit;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "AA").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
//            phone.sendSMS();
            phone2.sendSMS();
        }, "BB").start();
    }
}

//手机资源类,带发邮件、发短信功能
class Phone {
    //发邮件
    static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("sendEmail----->");
    }

    //发短信
    static synchronized void sendSMS() {
        System.out.println("sendSMS------->");
    }

    void sayHello() {
        System.out.println("sayHello------>");
    }


}

结果

1574948896560

场景七

1个静态同步方法 一个普通同步方法 一部手机

package com.zbiti.juc;

import java.util.concurrent.TimeUnit;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "AA").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.sendSMS();
//            phone2.sendSMS();
        }, "BB").start();
    }
}

//手机资源类,带发邮件、发短信功能
class Phone {
    //发邮件
    static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("sendEmail----->");
    }

    //发短信
    synchronized void sendSMS() {
        System.out.println("sendSMS------->");
    }

    void sayHello() {
        System.out.println("sayHello------>");
    }
}

结果

1574949828714

场景八

1个静态同步方法 一个普通同步方法 两部部手机

package com.zbiti.juc;

import java.util.concurrent.TimeUnit;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "AA").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
//            phone.sendSMS();
            phone2.sendSMS();
        }, "BB").start();
    }
}

//手机资源类,带发邮件、发短信功能
class Phone {
    //发邮件
    static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("sendEmail----->");
    }

    //发短信
    synchronized void sendSMS() {
        System.out.println("sendSMS------->");
    }

    void sayHello() {
        System.out.println("sayHello------>");
    }
}

结果

锁当前实例对象和锁当前类的Class对象是两个不同的对象,所以静态同步方法和非静态同步方法之间是不会有竞态条件的。但是一旦一个静态同步方法获取锁后,其它的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态同步方法之间,还是不同的实例对象静态同步方法之间

1574949828714

本文由博客一文多发平台 OpenWrite 发布!

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
2
获赞与收藏
7

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消