当前位置: 首页 > article >正文

【线程安全】ReentrantLock和synchronized的使用示例——言简意赅

三个进货员 分别进货 500000次、50000、50000次,一共应该进来600000箱; * 笔记:如何编写企业级的多线程代码 *
固定的变成套路+模板是什么?

不加synchronized、ReentrantLock每次都会导致不一样的结果
在这里插入图片描述
结果:
第一次运行
在这里插入图片描述
第二次运行
在这里插入图片描述

这就是线程不安全现象;

synchronized实现: 其中应用到了Lambda表达式,表达式未简化之前样式可见上面注释代码

package com.atguigu.signcenter.util;


import java.util.concurrent.locks.ReentrantLock;

/**
 * 题目:三个进货员 分别进货 500000次、50000、50000次,一共应该进来600000箱;
 * 笔记:如何编写企业级的多线程代码
 * 固定的变成套路+模板是什么?
 * 1. 在高内聚低耦合的前提下,线程   操作(资源类对外暴露的调用方法)  资源类
 * 1.1 一言不合,先创建一个资源类
 */
public class SaleTicketDemo {

     public static void main(String[] args) {  // 主线程,一切程序的入口
         Ticket ticket = new Ticket();

         // Thread(Runnable target, String name)
         // 使用匿名内部类
       /* new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 40; i++) {
                    ticket.saleTicket();
                }
            }
        }, "售票员1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 40; i++) {
                    ticket.saleTicket();
                }
            }
        }, "售票员2").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 40; i++) {
                    ticket.saleTicket();
                }
            }
        }, "售票员3").start();*/
         // 使用lambda表达式
         new Thread(() -> {for (int i = 1; i <= 500000; i++) ticket.saleTicket();}, "进货员1").start();
         new Thread(() -> {for (int i = 1; i <= 50000; i++) ticket.saleTicket();}, "进货员2").start();
         new Thread(() -> {for (int i = 1; i <= 50000; i++) ticket.saleTicket();}, "进货员3").start();
     }
 }

class Ticket {  // 资源类
    private int number = 0;
    private ReentrantLock lock = new ReentrantLock();  // 可重入锁

     public synchronized void saleTicket() {
        try {
            if (number >= 0) {
                number++;
                System.out.println("进货员进一箱水果,目前一共 = " + number);

            }
        } finally {
        }
    }

}

运行结果:
在这里插入图片描述

ReentrantLock使用

package com.atguigu.signcenter.util;


import java.util.concurrent.locks.ReentrantLock;

/**
 * 题目:三个进货员 分别进货 500000次、50000、50000次,一共应该进来600000箱;
 * 笔记:如何编写企业级的多线程代码
 * 固定的变成套路+模板是什么?
 * 1. 在高内聚低耦合的前提下,线程   操作(资源类对外暴露的调用方法)  资源类
 * 1.1 一言不合,先创建一个资源类
 */
public class SaleTicketDemo {

     public static void main(String[] args) {  // 主线程,一切程序的入口
         Ticket ticket = new Ticket();

         // Thread(Runnable target, String name)
         // 使用匿名内部类
       /* new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 40; i++) {
                    ticket.saleTicket();
                }
            }
        }, "售票员1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 40; i++) {
                    ticket.saleTicket();
                }
            }
        }, "售票员2").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 40; i++) {
                    ticket.saleTicket();
                }
            }
        }, "售票员3").start();*/
         // 使用lambda表达式
         new Thread(() -> {for (int i = 1; i <= 500000; i++) ticket.saleTicket();}, "进货员1").start();
         new Thread(() -> {for (int i = 1; i <= 50000; i++) ticket.saleTicket();}, "进货员2").start();
         new Thread(() -> {for (int i = 1; i <= 50000; i++) ticket.saleTicket();}, "进货员3").start();
     }
 }

class Ticket {  // 资源类
    private int number = 0;
    private ReentrantLock lock = new ReentrantLock();  // 可重入锁

//     public synchronized void saleTicket() {
    public void saleTicket() {
        lock.lock();
        try {
            if (number >= 0) {
                number++;
                System.out.println("进货员进一箱水果,目前一共 = " + number);

            }
        } finally {
            lock.unlock();
        }
    }

}

运行结果:
在这里插入图片描述


http://www.kler.cn/a/279808.html

相关文章:

  • 【Go语言基础】调度器模型GPM与垃圾回收器GC
  • 使用在AMD GPU上运行的ROCm进行大语言模型的自然语言处理任务
  • 每天一个数据分析题(五百零三)- 关联分析算法
  • Vue:快捷文本
  • 云计算day33
  • <数据集>脑肿瘤识别数据集<目标检测>
  • linux下一切皆文件,如何理解?
  • 【Python机器学习】NLP概述——自然语言智商
  • 未来网络安全展望:量子计算对传统加密的挑战与机遇
  • Django 后端架构开发:存储层调优策略解析
  • Android Radio实战——有效电台列表(十六)
  • ​经​纬​恒​润​一​面​
  • SQL Server 查询语句中,对索引列做CONVERT的影响
  • 华为Cloud连接配置
  • D - Pairs 二分+二分
  • SAP主数据删除
  • vue3编程 -动态多开模态框实现方案
  • mac/windows 软件推荐
  • MySql字段有null值与其他值的比较
  • 【JVM】剖析字符串与数组的底层实现(二)