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

idea debug功能演示线程安全问题

概述

用idea debug功能演示上一篇博客中提到的

本实现中的出队、入队的实现逻辑会不会有线程安全问题?如果有,怎么解决?

测试用例

package com.lovehena.datastructure.test;

import com.lovehena.datastructure.ArrayQueue;

/*
* 测试 offer() poll()方法的线程安全问题
* */
public class TestArrayQueue2 {
    /**
     *  测试 offer() 方法的线程安全问题
     * @param args
     */
    public static void main(String[] args) throws InterruptedException {
        ArrayQueue queue = new ArrayQueue(3);

        /**
         *  预期是 线程1将1入队 线程2将2入队
         *  但由于可能发生指令交错 导致线程安全问题 则可能的结果是 队列中只有2 或者 只有1
         *  用idea debug功能模拟
         */
        Thread t1 = new Thread(() -> {
            queue.offer(1);
        }, "t1");

        Thread t2 = new Thread(() -> {
            queue.offer(2);
        }, "t2");

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

        // 等待t1、t2线程执行完毕
        t1.join();
        t2.join();

        // 打印得到的queue
        queue.print();
    }
}

演示

文字不好叙述,录制了一个视频。

测试用例输出

元素2将元素1覆盖的情形

元素2将元素1覆盖的情形

元素1将元素2覆盖的情形

元素1将元素2覆盖的情形

解决线程安全问题

常见思路就是加锁。
我这个不涉及集群部署,所以用synchronized、lock(java.util.concurrent.locks.Lock)实现即可。
代码示例

	// 多个线程往同一队列中入队元素时,确保锁是同一个。
	// 一般将锁对象设置为队列的一个成员变量
	private ReentrantLock lock=new ReentrantLock(); // 控制offer的锁
	public boolean offer(int value) {
        lock.lock(); // 加锁成功后 以下代码才会被执行
        try {
            if (tail == capacity) { //队列放满了
                log.info("元素 {} 入队失败 因为队列放满了", value);
                return false;
            }
            arr[tail] = value;
            tail++;
        }finally {
            lock.unlock(); // 一定要记得手动释放锁 否则导致其他线程无法获取到锁 进而无法入队元素
        }
        return true;
    }

以上代码经测试,不会再有线程安全问题。

扩展

测试poll()方法的线程安全问题。

加锁解决poll()方法的线程安全问题。

最后

好了,如果对你有帮助的话,欢迎点个免费的赞哦。

相关文章:

  • MATLAB学习之旅:数据建模与仿真应用
  • Autosar Com配置-Timeout配置及实现-基于ETAS工具
  • 解决“error: Tried to call obs_frontend_start_virtualcam with no callbacks!”
  • Tio-Boot 集成 Spring Boot 实现即时通讯功能全解析
  • 运维脚本——9.配置漂移检测
  • 【Linux内核】进程管理(下)
  • directx12 3d开发过程中出现的报错 十三
  • 全链路优化:如何让单点登录认证接口并发性能翻倍?
  • 鸿蒙开发环境搭建-入门篇
  • 网络运维学习笔记 017 HCIA-Datacom综合实验01
  • 区块链相关方法-SWOT分析
  • 侯捷 C++ 课程学习笔记:内存管理与工具应用
  • socket()函数的概念和使用案例
  • Java 使用websocket
  • 【Linux】34.封装 UdpSocket(1)
  • 【读书笔记·VLSI电路设计方法解密】问题53:什么是逻辑综合
  • bind()函数的概念和使用案例
  • WPF实现打印机控制及打印
  • JavaScript 数组连接方法
  • java中的Entry类,map接口
  • 重庆荣昌区委区政府再设“答谢宴”,邀请800余名志愿者机关食堂用餐
  • 异域拾异|大脚怪的形状:一项神秘社会学研究
  • 山寨“小米”智能马桶、花洒销售额过亿,被判赔3500万元
  • 波音公司计划于2027年交付新版“空军一号”飞机
  • “用鲜血和生命凝结的深厚情谊”——习近平主席署名文章中的中俄友好故事
  • 王耀庆化身“罗朱”说书人,一人挑战15个角色