juc笔记之synchronized和lock的使用

news/2024/5/20 10:19:50 标签: 并发编程, juc

文章目录

  • 一、锁是什么?
  • 二、使用步骤
    • 1.synchronized
    • 2.lock
  • 三、总结

一、锁是什么?

我们都知道,在多线程的环境下,是会引发线程安全的问题的,那么针对这一问题,java提供了synchronized和lock锁机制来控制线程的并发访问,简单来说锁是用来防止多线程操作同一段资源,以防止出现错误的执行结果。
那下面来讲简单介绍一下两种锁的使用方式吧!

二、使用步骤

1.synchronized

以卖票为例子:

package com.lhh.demo;


/**
 *
 * @param
 * @author HaiHui
 * @date 2021/1/29 10:35
 * @return
 */
public class Tickle1 {
    private int number = 30;

    public synchronized void sale() {
        //业务代码
        if (number > 0) {
        //引入两行代码是为了检测假如不加synchronized会造成怎样的后果。
            System.out.println(Thread.currentThread().getName() + "卖出了" + (number--) + "票,剩余" + number);
            System.out.println(Thread.currentThread().getName());
        }
    }
}

在这里插入图片描述

2.lock

我们还是以卖票为例:

  • 创建ReteenLock对象
  • lock加锁
  • 中间是业务代码
  • unlock解锁
package com.lhh.demo;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
*
*  使用Lock三部曲
 *  1.创建ReteenLock对象
 *  2.lock.lock()  加锁
 *  3.lock.unlock() 解锁
* @author HaiHui
* @date 2021/1/29 10:35
* @param
* @return
*/
public class Tickle {
    private int number = 30;
    Lock lock = new ReentrantLock();//可重入锁

    public void sale() {
        lock.lock();/*开启锁*/
        try {
            //业务代码
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "卖出了" + (number--) + "票,剩余" + number);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();/*解锁,必须配对,假如有多个lock.lock()操作,那么就需要多次解锁。*/
        }
    }
}

接下来,我们测试一下卖票的过程:

package com.lhh.demo;

public class TickleDemo {
    public static void main(String[] args) {
        //多线程操作统一资源Tickle,并发编程的要求,把tickle资源丢入线程即可。
        Tickle tickle = new Tickle();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                tickle.sale();
            }
        }, "A").start();


        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                tickle.sale();
            }
        }, "B").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                tickle.sale();
            }
        }, "C").start();
    }
}

在这里插入图片描述
声明一点,这里不是按照abc的顺序执行是因为可重入锁ReteenLock的构造方法没有加true参数,默认就是非公平锁,cpu默认随机切换线程执行,如果指定为true的话,那么就是按照严格的顺序执行了,必须是一个线程执行完毕之后释放锁,后面的线程才能被执行。

三、总结

区别:
相同点:

  • 他们都是重入锁
  • 他们都可以用来控制多线程环境下的线程安全问题

不同点:

  • synchronized是一个关键字,而lock是一个java类
  • synchronized无法获取锁的状态,而lock可以做到
  • synchronized可以自动释放锁,而lock需要手动释放,不释放会死锁
  • synchronized适合少量的代码同步代码,而lock释放大量的同步代码
  • synchronized可能引发线程无线等待(拿到锁的线程突然由于某种原因阻塞了,那么造成后面需要该锁的线程一直无限期的等待下去),而lock不一定

http://www.niftyadmin.cn/n/1085768.html

相关文章

ThinkCMF如何关闭右下角的trace图标

版本 ThinkCMF - 5.1.5 方法 关闭前端右下角跟踪调试按钮 修改/public/index.php把第15行的APP_DEBUG设置为false图示

手机电子词典_这些好用的手机词典,你都知道吗?

南京英孚青少儿英语于2002年成立&#xff0c;16年来深耕南京。专注3-18岁孩子英语教育&#xff0c;英语启蒙、英文阅读兴趣、考试学习、出国留学来英孚就够了。我们的运行及管理遵照EF全球统一模式。50年专业英语教育经验值得信赖&#xff0c;关注英语&#xff0c;关注孩子。电…

juc笔记之callable详解

文章目录一、Callable是什么二、使用步骤1.自定义类实现callable接口2.测试三、总结一、Callable是什么 它是一个接口&#xff0c;位于juc包下&#xff0c;代表一个异步的任务&#xff0c;在多线程环境下&#xff0c;使用callable更明智&#xff0c;因为有些时候&#xff0c;我…

网页版word编辑器_印象笔记全新网页版编辑器公测——资深用户告诉你,怎......

印象笔记新版网页版编辑器开启公测。时隔两年之后&#xff0c;印象笔记网页编辑器再一次迎来了大升级&#xff0c;今天的干货分享来自印象大使嘉里老师&#xff0c;他通过详细对比近年来3个版本的印象笔记网页编辑器所带来的用户体验&#xff0c;为我们使用印象笔记带来更多的启…

Linux+MySQL错误: ERROR 1018 (HY000): Can't read dir of '.' (errno: 13 - Permission denied)

环境 Ubuntu 18.04.4 LTS MySQL 错误 mysql> show databases; ERROR 1018 (HY000): Cant read dir of . (errno: 13 - Permission denied) 解决办法 chown -R mysql:mysql /var/lib/mysql/ chmod -R 755 /var/lib/mysql/ 截图

juc笔记之常用辅助类

文章目录一、辅助类是什么&#xff1f;二、使用步骤1.CountDownLatch2.CyclicBarrier3.Semaphere三、总结一、辅助类是什么&#xff1f; juc里面有三大辅助类&#xff0c;分别是CountDownLatch&#xff0c;CyclicBarrier以及Semaphere。 第一个是减法计数器&#xff0c;作为需…

ThinkCMF文件上传失败,“未定义数组索引: multi”

PHP版本 7.4.1 ThinkCMF版本 v5.1.39 LTS (如何查看CMF版本&#xff1a;cd /path/to/project/; php think version) OSX 10.14.4 文件1: /vendor/thinkcmf/cmf-app/src/user/controller/AssetController.php 修改 View::share(max_files, $arrData["multi"] ? …

ThinkCMF后台错误:Trying to access array offset on value of type null --- name=cmf_settings[banned_usern

PHP版本 7.4.1 ThinkCMF版本 v5.1.39 LTS (如何查看CMF版本&#xff1a;cd /path/to/project/; php think version) OSX 10.14.4 解决办法 修改 /public/themes/admin_simpleboot3/admin/setting/site.html 从 name"cmf_settings[banned_usernames]">{$cmf_…