1. 对象上有关键字
package com.study.juc.sync;

import java.util.concurrent.TimeUnit;

public class Test1 {

    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Thread t1= new Thread(()->{
            try {
                phone.sendSms();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        },"A");
        t1.start();

        TimeUnit.SECONDS.sleep(1);

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

        t2.start();

        Thread t3=new Thread(()->{
            phone.hello();
        },"c");

        t3.start();
    }

}


class Phone{

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

    public synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("发短信");
    }

    public void hello(){
        System.out.println("hello ");
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.

请输出上面例子的结果。

  • 结论
    如果时同一个对象上,加 synchronized 那么这个对象的一个方法先进入,另外的方法只能等待,需要登台获取锁的对象完成才能执行。
    如果方法上没有锁,那么不会等待。
  1. 两个对象的调用
package com.study.juc.sync;


import java.util.concurrent.TimeUnit;

public class Test2 {

    public static void main(String[] args) throws InterruptedException {
        Phone2 phone1 = new Phone2();
        Phone2 phone2 = new Phone2();
        Thread t1= new Thread(()->{
            try {
                phone1.sendSms();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        },"A");
        t1.start();

        TimeUnit.SECONDS.sleep(1);

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

        t2.start();


    }

}


class Phone2{

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

    public synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("发短信");
    }

    public void hello(){
        System.out.println("hello ");
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.

创建两个对象,分别调用其方法,由于是两个对象,锁的作用范围也是对象,因此两个对象的锁不互相干扰。

  1. 静态方法
package com.study.juc.sync;


import java.util.concurrent.TimeUnit;

public class Test3 {

    public static void main(String[] args) throws InterruptedException {

        Phone3 phone1 = new Phone3();
        Phone3 phone2 = new Phone3();
        Thread t1= new Thread(()->{
            try {
                phone1.sendSms();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        },"A");
        t1.start();

        TimeUnit.SECONDS.sleep(1);

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

        t2.start();
    }
}


class Phone3{

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

    public static synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("发短信");
    }

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.

synchronized 作用在 class 上,所以锁的对象是 class。

  1. 一个实例方法,一个类方法
package com.study.juc.sync;


import java.util.concurrent.TimeUnit;

public class Test4 {

    public static void main(String[] args) throws InterruptedException {


        Phone4 phone = new Phone4();
        Thread t1= new Thread(()->{
            try {
                phone.sendSms();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        },"A");
        t1.start();

        TimeUnit.SECONDS.sleep(1);

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

        t2.start();


    }

}


class Phone4{

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

    public static synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("发短信");
    }

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

一个调用静态方法,一个调用实例方法,实际是两把锁相互不影响。