Java高并发之魂-synchronized深度解析 学习笔记(1)- 对象锁和类锁

1 Synchronized

1.1 作用

在这里插入图片描述
在这里插入图片描述

一句话概括:

  • 能够保证 同一时刻 最多只有 一个 线程执行该段代码,以达到保证并发安全的效果。

1.1 不使用并发手段的后果

public class DisappearRequest1 implements Runnable {

    static DisappearRequest1 instance = new DisappearRequest1();

    static int i = 0;

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

        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println(i);
    }

    @Override
    public void run() {
        for (int j = 0; j < 100000; j++) {
            i++;
        }
    }
}

在这里插入图片描述
在这里插入图片描述

2 Synchronized 的两个用法

2.1 对象锁

包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)


代码块形式:手动指定锁对象
方法锁形式: synchronized 修饰普通方法,锁对象默认是 this


在这里插入图片描述

/**
 * @Description 对象锁案例1,代码块形式
 * @Author tzb
 * @Date 2020/12/16 22:56
 * @Version 1.0
 **/
public class SycchronizedObjecfCodeBlock2 implements Runnable {

    static SycchronizedObjecfCodeBlock2 instance = new SycchronizedObjecfCodeBlock2();

    @Override
    public void run() {

        synchronized (this) {
            System.out.println("我是对象锁的代码块形式,我叫" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "运行结束");
        }


    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);

        t1.start();
        t2.start();

        while (t1.isAlive() || t2.isAlive()) {

        }

        System.out.println("finished");

    }

}

在这里插入图片描述


public class SycchronizedObjecfCodeBlock2 implements Runnable {

    static SycchronizedObjecfCodeBlock2 instance = new SycchronizedObjecfCodeBlock2();

    Object lock1 = new Object();
    Object lock2 = new Object();

    @Override
    public void run() {

        synchronized (lock1) {
            System.out.println("我是lock1,我叫" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " lock1运行结束");
        }

        synchronized (lock2) {
            System.out.println("我是lock2,我叫" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " lock2运行结束");
        }


    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);

        t1.start();
        t2.start();

        while (t1.isAlive() || t2.isAlive()) {

        }

        System.out.println("finished");

    }

}

在这里插入图片描述


2.1.1 调试技巧 - 看线程的生命周期

public class SycchronizedObjecfCodeBlock2 implements Runnable {

    static SycchronizedObjecfCodeBlock2 instance = new SycchronizedObjecfCodeBlock2();

    @Override
    public void run() {

        synchronized (this) {
            System.out.println("我是对象锁的代码块形式,我叫 " + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 运行结束");
        }

    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);

        t1.start();
        t2.start();

        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");

    }

}

在这里插入图片描述


  • 断点处右击

  • All : 会把整个 jvm停止,包括其他的线程

  • thread : 只会停止当前的线程
    在这里插入图片描述

  • 线程0: Runnable
    在这里插入图片描述

  • 线程1
    在这里插入图片描述
    在这里插入图片描述


2.1.2 对象锁的形式2-普通方法锁

/**
 * @Description 对象锁实例2-方法锁
 * @Author tzb
 * @Date 2021/1/4 22:55
 * @Version 1.0
 **/
public class SynchronizedObjectMethod3 implements Runnable {

    static SynchronizedObjectMethod3 instance = new SynchronizedObjectMethod3();

    public static void main(String[] args) {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);

        t1.start();
        t2.start();

        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");

    }

    @Override
    public void run() {
        method();
    }

    public synchronized void method(){
        System.out.println("我是对象锁的方法修饰符形式,我叫 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(Thread.currentThread().getName() + " 运行结束");
    }

}

在这里插入图片描述

2.2 类锁

synchronized 修饰静态的方法或指定为 Class对象
在这里插入图片描述
在这里插入图片描述

2.2.1 类锁的形式1- 静态方法锁

  • 不加 static
public class SynchronizedClassStatic4 implements Runnable {

    static SynchronizedClassStatic4 instance1 = new SynchronizedClassStatic4();
    static SynchronizedClassStatic4 instance2 = new SynchronizedClassStatic4();

    @Override
    public void run() {
        method();
    }

    public  synchronized void method() {
        System.out.println("我是类锁的第一种形式:static形式,我叫 " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 运行结束");
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);

        t1.start();
        t2.start();

        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");

    }
}

在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

2.2.2 类锁的形式2- .class

  • 反例 this
public class SynchronizedClassClass5 implements Runnable{

    static SynchronizedClassClass5 instance1 = new SynchronizedClassClass5();
    static SynchronizedClassClass5 instance2 = new SynchronizedClassClass5();

    @Override
    public void run() {

    }

    private void method() throws InterruptedException {
        synchronized (this){
            System.out.println("我是类锁的第二种形式:synchronized(*.class),我叫" +Thread.currentThread().getName());
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName()+" 执行完毕");
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);

        t1.start();
        t2.start();

        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");

    }
}

在这里插入图片描述


  • 修改为 .class
    在这里插入图片描述
    在这里插入图片描述
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页