20-「季淳卿」线程同步和不同步、线程锁案例

本文由季纯卿讲解线程同步与线程不同步的概念,强调线程安全与效率的权衡。介绍了AQS(AbstractQueuedSynchronizer)作为同步器框架,及其实现类如ReentrantLock、CountDownLatch等。重点讨论了可重入锁ReentrantLock的原理和使用,包括公平锁与非公平锁的区别,并通过代码示例展示了ReentrantLock的加锁与解锁操作。

前言

hello,大家好!这里季纯卿 ,别来无恙
Java基础专栏点击
今天接上一章开始学习:

线程同步和线程不同步

基本数据类型

线程同步:同一时间只有一个执行

  • 线程安全的场景
  • 数据是安全的,但是处理效率会低一些

数据不同步:很有可以capy为同一个值,(多个线程同时在操作一个对象)

  • 线程不安全的场景
  • 数据是不安全的,但是处理效率会高一些
  • 线程不安全有的时候可以容忍(因为同步,按照一条一条的处理,违背了多线程)

线程安全:执行效率低一些
线程不安全:执行效率高一些

线程锁

想要线程处理速度高一点,然后数据尽可能安全,这个时候就可以用到线程之间的锁
锁就是让原来不同步的模式,短暂变得同步
目的:就是为了处理线程不安全,导致数据不一致的问题,

在需要的时候同步,不需要不同步
(在某一个场景类,需要)

比如在下列代码释放中只需要在count++的时候同步,其他的时候都不需要同步
确保这个count出来的数据他是一个正确的数据

线程一个一个的修改,才能保证线程安全

1. AQS(Abstract Queued Synchronizer)抽象队列同步

Java中的同步器的框架
这个同步器类里面定义了:如何去对线程加锁

1.2 实现类

CountDownLatch(倒计时锁)
ReentrantLock(重入锁) [ 用的最多 ]
ReentrantReadwriteLock(可重入写锁)
Semaphore(信号灯)

1.3 可重入的互斥锁 - ReentrantLock

(一个线程你在等待的时候,CPU就不会管你 了,会把资源释放给其他的任务进行处理)
默认情况下:采用的非公平模式

解锁
一旦调用lock()方法加锁,就一个要调用unlock()解锁
如果没有解锁就会把后面所有的线程锁死,这是一个很严重的问题

1.3.1 可重入

举个例子:我们在门上装了一把锁,这个时候有三个人走过来了,此时三个人同时抓住了这个门把手,但是钥匙孔只有一个。那么先拿钥匙开门的这个人,他就可以先开门走。另外两个人也想开门但是他们要等着别人,但是你等着别人在Java的执行过程当中,就会有一个情景发生,一个线程在等的过程当中,CPU就不会管你 了,会把资源释放给其他的任务进行处理。
这个时候第一个人开完门已经走路,走了之后,基于排队的机制已经有两个人抓找门把手上面了,他们只需要拿钥匙开门。第一个人处理完了,后面的两个人也要处理。
什么叫做可重入呢?就是这两个人再次进来的时候可以直接拿钥匙开门,就是他再次进来的时候,恢复到最后一次阻塞的位置。

1.3.2 不可重入

举个例子:就是三个人同时抓住这个门把手,只用一个人抢到了这个钥匙孔开门去了
不可重入概念就是:当这个人抢到了这个钥匙孔去开门的一刹那,抓着门把手的着两个就都会被踢除,之后他们就又要先去抢门把手才能开门

1.4 互斥锁

只要一个人抢到了锁,另外一个人就别想抢了

  • 只能有一个线程访问被保护的资源
    锁的定义在Lock里面

1.5 共享锁

大家都可以使用同一个把锁(允许多个线程共同访问资源)
也就是上面可重用的概念

1.6 公平锁:

就是所有人一个一个的依次去处理

1.7 非公平锁

先抢这个,没抢到,也要去抢

读锁
解锁

& - [ 代码 ] 锁的实现

public class CounterRun implements Runnable {
    private static int count = 0;
    private static int count1 = 0;
    ReentrantLock lock = new ReentrantLock();//1-
//    CountDownLatch counter = new CountDownLatch(200);
//    Semaphore semaphore = new Semaphore(200);

    public static void main(String[] args) {
        for (int i = 0; i < 1000; i++) {
            SynchronizedText s = new SynchronizedText();
            s.start();
        }
    }

    @Override
    public void run() {
        counter();
        sayHello();

    }

    //同步方法
    public synchronized void sayHello() {
        count++;
        System.out.println("count0:" + count);
    }

    public void counter() {
     /*   counter.await();
        counter.countDown();
        semaphore.acquire();
        semaphore.release();*/
        lock.lock();//加锁  ReentrantLock 一旦加锁,必须手动释放unlock
        count1++;
        lock.unlock();//解锁
        System.out.println("count1:" + count1);
    }

    public static int getCount() {
        return count;
    }

    public static void setCount(int count) {
        CounterRun.count = count;
    }

    public static int getCount1() {
        return count1;
    }

    public static void setCount1(int count1) {
        CounterRun.count1 = count1;
    }

}
public class synchronizedText {
    public static void main(String[] args)
    {
        CounterRun cr = new CounterRun();
        for (int i = 0; i < 1000 ; i++)
        {
            Thread s = new Thread(cr);
            Thread s1 = new Thread(cr);
            Thread s2 = new Thread(cr);
            Thread s3 = new Thread(cr);
            Thread s4 = new Thread(cr);
            s.start();
            s1.start();
            s2.start();
            s3.start();
            s4.start();
        }

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(CounterRun.getCount()+"=="+CounterRun.getCount1());

    }


}

本节学习结束啦✿✿ヽ(°▽°)ノ✿
有什么问题欢迎大家提出来,一起进步

世界灿烂盛大,欢迎回家 —— 《全球高考》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

季淳卿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值