Synchronized介绍

2021-11-04 09:58:21 浏览数 (1)

简介

synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种: 

  • 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象; 
  • 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象; 
  • 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象; 
  • 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
代码语言:javascript复制
synchronized和lock区别:
1.synchronized是一个内置的java关键字;lock是一个java类
2.synchronized无法判断锁状态;lock可以判断锁状态;
3.synchronized会自动释放锁;lock必须手动释放锁;
4.synchronized获取锁(线程A获得锁,阻塞其他线程;线程B被阻塞,一直傻傻等);lock就不一定会傻傻等;
5.synchronized是可重入锁,不可中断的锁,非公平锁;lock是可重入锁 非公平(可以自己设置);
6.synchronized适合少量的代码同步问题;lock适合大量的同步代码;

实例代码

描述:标准情况下,两个线程谁先打印。

代码语言:javascript复制
public class ThreadDemo {

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

        Phone phone = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }, "A").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.call();
        }, "A").start();
    }
}
class  Phone {

    // synchronized锁的对象是方法的调用者 谁先拿到,谁先执行
    public synchronized void sendSms() {
        System.out.println("发短信");
    }

    // synchronized锁的对象是方法的调用者
    public synchronized void call() {
        System.out.println("打电话");
    }
}
发短信
打电话

描述:sendSms延迟4秒,两个线程谁先打印。

代码语言:javascript复制
public class ThreadDemo {

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

        Phone phone = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }, "A").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.call();
        }, "A").start();
    }
}
class  Phone {

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

    // synchronized锁的对象是方法的调用者
    public synchronized void call() {
        System.out.println("打电话");
    }
}

发短信
打电话

描述:新增一个普通方法hello

代码语言:javascript复制
public class ThreadDemo3 {
    public static void main(String[] args) throws Exception{

        Phone3 phone = new Phone3();
        new Thread(() -> {
            phone.sendSms();
        }, "A").start();

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.hello();
        }, "A").start();
    }
}
class Phone3 {

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

    // synchronized锁的对象是方法的调用者
    public synchronized void call() {
        System.out.println("打电话");
    }

    public void hello() {
        System.out.println("你好呀");
    }
}
你好呀
发短信

描述:两个对象调用两个同步方法

代码语言:javascript复制
public class ThreadDemo4 {
    public static void main(String[] args) throws Exception{

        // 两个对象
        Phone4 phone = new Phone4();
        Phone4 phone2 = new Phone4();

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

        TimeUnit.SECONDS.sleep(2);

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

class Phone4 {

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

    // synchronized锁的对象是方法的调用者
    public synchronized void call() {
        System.out.println("打电话");
    }
}
打电话
发短信

描述:增加两个静态的同步方法,在一个对象和两个对象的前提下。

代码语言:javascript复制
public class ThreadDemo5 {
    public static void main(String[] args) throws Exception{

        Phone5 phone = new Phone5();

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

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.call();
        }, "A").start();
    }
}

class Phone5 {

    // static静态方法,属于类的,所以锁的是类Class
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    // synchronized锁的对象是方法的调用者
    public static synchronized void call() {
        System.out.println("打电话");
    }
}
发短信
打电话

public class ThreadDemo5 {
    public static void main(String[] args) throws Exception{

        Phone5 phone = new Phone5();
        Phone5 phone2 = new Phone5();

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

        TimeUnit.SECONDS.sleep(2);

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

class Phone5 {

    // static静态方法,属于类的,所以锁的是类Class
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    // static静态方法,属于类的,所以锁的是类Class
    public static synchronized void call() {
        System.out.println("打电话");
    }
}
发短信
打电话

描述:一个静态同步方法,一个普通同步方法;在一个对象和两个对象的前提下。

代码语言:javascript复制
public class ThreadDemo6 {
    public static void main(String[] args) throws Exception{

        Phone6 phone = new Phone6();

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

        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            phone.call();
        }, "A").start();
    }
}

class Phone6 {

    // static静态方法,属于类的,所以锁的是类Class
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    // synchronized锁的对象是方法的调用者
    public synchronized void call() {
        System.out.println("打电话");
    }
}
打电话
发短信

public class ThreadDemo6 {
    public static void main(String[] args) throws Exception{

        Phone6 phone = new Phone6();
        Phone6 phone2 = new Phone6();

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

        TimeUnit.SECONDS.sleep(2);

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

class Phone6 {

    // static静态方法,属于类的,所以锁的是类Class
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    // synchronized锁的对象是方法的调用者
    public synchronized void call() {
        System.out.println("打电话");
    }
}
打电话
发短信

0 人点赞