【并发编程篇】Synchronized和Lock的零碎知识点

发布时间:2023年12月17日

在这里插入图片描述

🌹什么是juc

JUC(Java Util Concurrent)是Java平台提供的一个并发编程工具包,它包含了一系列用于多线程编程的类和接口。JUC提供了更高层次的抽象,简化了并发编程的复杂性,并提供了更高效、更安全的并发编程解决方案。

JUC提供了以下几个核心概念和组件:

  • 并发集合(Concurrent Collections):JUC提供了一些线程安全的集合类,如ConcurrentHashMap、ConcurrentLinkedQueue等,用于在多线程环境下进行安全的数据共享和操作。

    同步器(Synchronizers):JUC提供了一些同步器类,如CountDownLatch、CyclicBarrier、Semaphore等,用于协调多个线程之间的执行顺序和互斥访问。

    原子变量(Atomic Variables):JUC提供了一些原子变量类,如AtomicInteger、AtomicLong等,用于在不需要加锁的情况下实现线程安全的原子操作。

    线程池(Executor Framework):JUC提供了线程池框架,通过线程池可以更好地管理和控制线程的创建、执行和销毁,提高了线程的复用性和性能。

    并发工具类(Concurrent Utilities):JUC提供了一些并发编程中常用的工具类,如Lock、Condition、ReadWriteLock等,用于实现更灵活的线程同步和控制。

JUC的引入使得Java开发者能够更方便地编写高效、线程安全的并发程序,提高程序的性能和可维护性。

🛸线程和进程

线程:比如我打开了微信,操作系统会为微信应用程序创建一个进程
进程:比如我正在写文章,这就是进程

🌺Synchronize锁的注意点

package com.kuang.pc;
/**
 * 线程之间的通信问题:生产者和消费者问题! 等待唤醒,通知唤醒
 * 线程交替执行 A B 操作同一个变量 num = 0
 * A num+1
 * B num-1
 */
public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
    }
}
// 判断等待,业务,通知
class Data{ // 数字 资源类
    private int number = 0;
    //+1
    public synchronized void increment() throws InterruptedException {
        if (number!=0){ //0
// 等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
// 通知其他线程,我+1完毕了
        this.notifyAll();
    }
    //-1
    public synchronized void decrement() throws InterruptedException {
        if (number==0){ // 1
// 等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
// 通知其他线程,我-1完毕了
        this.notifyAll();
    }
}

== 虚假唤醒 ==

在这里插入图片描述
遇到这种情况,我们直接把if改为while即可

package com.kuang.pc;
/**
 * 线程之间的通信问题:生产者和消费者问题! 等待唤醒,通知唤醒
 * 线程交替执行 A B 操作同一个变量 num = 0
 * A num+1
 * B num-1
 */
public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();
    }
}
// 判断等待,业务,通知
class Data{ // 数字 资源类
    private int number = 0;
    //+1
    public synchronized void increment() throws InterruptedException {
        while (number!=0){ //0
// 等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
// 通知其他线程,我+1完毕了
        this.notifyAll();
    }
    //-1
    public synchronized void decrement() throws InterruptedException {
        while (number==0){ // 1
// 等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
// 通知其他线程,我-1完毕了
        this.notifyAll();
    }
}

🎄Synchronized 和 Lock 区别

1、Synchronized 内置的Java关键字, Lock 是一个Java类
2、Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
3、Synchronized 会自动释放锁,lock 必须要手动释放锁!如果不释放锁,死锁
4、Synchronized 线程 1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下
去;
5、Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以 判断锁,非公平(可以
自己设置);
6、Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!

在技术的道路上,我们不断探索、不断前行,不断面对挑战、不断突破自我。科技的发展改变着世界,而我们作为技术人员,也在这个过程中书写着自己的篇章。让我们携手并进,共同努力,开创美好的未来!愿我们在科技的征途上不断奋进,创造出更加美好、更加智能的明天!

在这里插入图片描述

文章来源:https://blog.csdn.net/m0_72853403/article/details/135032399
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。