Java synchronized

isen
isen
发布于 2023-09-25 / 21 阅读 / 0 评论 / 0 点赞

Java synchronized

一、sychronized

在 java 中,每个对象都有一个对象监视器,或者说对象锁。 synchronized(obj) 是尝试获取对象obj的对象锁,只有成功获取对象锁后,线程才能执行 synchronized 作用的代码,否则线程会处于 BLOCK 状态。由于对象锁是一个独占锁,所以在同一时刻,只有一个线程能够成功获取对象锁。

sychronized 作用说明:
当线程访问“对象”的 sychronized 的方法或者代码块时,其他线程无法同时访问该方法或者代码块,也无法访问该“对象”的其他sychronized 方法或者代码,但是可以访问该“对象”的非 syhronized 方法或者代码,并且也可以访问其他“对象”的方法或者代码块。

上述说明中,“对象”是指 sychronized 需要获取对象锁的对象。

总之,获取同一个对象锁的 synchronized 互斥。

sychronized 实例方法和静态方法,分别获取实例对象和类对象的对象锁。

二、示例

public class SychronizedDemo {

    private int age = 10;

    private static String name = "isen";

    private synchronized int getAge(){
        System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的实例对象的对象锁,进入getAge()方法");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 退出getAge()方法");
        return age;
    }

    private synchronized void setAge(int age){
        System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的实例对象的对象锁,进入setAge()方法");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.age = age;
        System.out.println(Thread.currentThread().getName() + " 退出setAge()方法");
    }

    private void printAge(){
        System.out.println(Thread.currentThread().getName() + " 进入printAge()方法");
        synchronized (this){
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的实例对象的对象锁,进入synchronized (this)代码块");
            System.out.println("age = " + age);
        }
        System.out.println(Thread.currentThread().getName() + " 退出printAge()方法");
    }

    private synchronized static String getName(){
        System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的类对象的对象锁,进入getName()方法");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 退出getName()方法");
        return name;
    }

    private synchronized static void setName(String name){
        System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的类对象的对象锁,进入setName()方法");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        SychronizedDemo.name = name;
        System.out.println(Thread.currentThread().getName() + " 退出setName()方法");
    }

    private static void printName(){
        System.out.println(Thread.currentThread().getName() + " 进入printName()方法");
        synchronized (SychronizedDemo.class){
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 成功获取 SychronizedDemo 的类对象的对象锁,进入printName()方法");
            System.out.println("name = " + name);
        }
        System.out.println(Thread.currentThread().getName() + " 退出printName()方法");
    }

    private void catAge(){
        System.out.println(Thread.currentThread().getName() + " 进入catAge()方法");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 退出catAge()方法");
    }

    private static void catName(){
        System.out.println(Thread.currentThread().getName() + " 进入catName()方法");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 退出catName()方法");
    }

    public static void main(String[] args) {
        SychronizedDemo sychronizedDemo = new SychronizedDemo();

        new Thread(){
            @Override
            public void run() {
                sychronizedDemo.getAge();
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                sychronizedDemo.setAge(12);
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                sychronizedDemo.printAge();
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                SychronizedDemo.getName();
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                SychronizedDemo.setName("lisi");
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                SychronizedDemo.printName();
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                sychronizedDemo.catAge();
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                SychronizedDemo.catName();
            }
        }.start();
    }
}