继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

static和synchronized

libingshen
关注TA
已关注
手记 21
粉丝 2
获赞 7

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 发布!

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP