案例07-在线人员列表逻辑混乱

简介: 在线人员列表逻辑混乱

一、背景介绍

在线人员列表涉及到的问题:

类中写了公共变量最后导致数据混乱现象

保存数据没有考虑业务的隔夜覆盖导致的逻辑漏洞

涉及到继承,对于this,如果父类有同样的成员最终使用哪一个?

参数不一致导致后续维护混乱

mysql由于关联字段类型不一致导致产生索引失效问题,进而产生慢sql

sql不考虑业务导致有明显的逻辑漏洞

上面的问题主要分为四类问题:

公共变量导致数据混乱

对于在线人员的业务存在逻辑问题(对应上面的 2 4 6 )

面向对象继承的问题,this.属性和方法的问题

mysql由于关联字段类型不一致导致索引失效的问题。    

二、解决过程

1.类中写了公共变量最后导致数据混乱现象

aa469fed877c49a795b2afff069224bf.png

原因:由于线程共享全局变量,并且在实际业务的过程中对全局变量进行了操作(修改),所以在高并发、多线程的条件下会产生公共变量导致数据混乱的现象。

方案:1.使用ThreadLocal

ThreadLocal叫做线程变量,该变量对于其他线程而言是隔离的,该变量是当前该线程独有的变量。它与普通变量的区别在于,每个使用该变量的线程都会初始化一个完全独立的实例副本。正是由于每个线程都有自己的实例副本,且与其他线程不可访问,那就不存在多线程共享该变量的问题。

没使用ThreadLocal之前

代码编写

public class Client {
    public static void main(String[] args) {
        // 定义线程实现接口
        Runnable runnable = new Runnable(){
            Counter counter = new Counter();
            @Override
            public void run() {
                counter.count();
            }
        };
        // 启动10个线程
        for( int i= 0;i< 10;i++) {
            new Thread(runnable).start();
        }
    }
}
public class Counter{
 private int number;
     public void count(){
        for (int i = 0; i <=10 ; i++) {
            number=number+i;
        }
        System.out.println(Thread.currentThread().getName()+ "--"+number;
    }
}

执行结果:计算的结果应该都为55,结果出现了混乱的情况

4fd3a1f91f8e415e9df5f17c33f5e9e1.png

使用ThreadLocal之后

public class Client {
    public static void main(String[] args) {
        // 定义线程实现接口
        Runnable runnable = new Runnable(){
            Counter counter = new Counter();
            @Override
            public void run() {
                counter.count();
            }
        };
        // 启动10个线程
        for( int i= 0;i< 10;i++) {
            new Thread(runnable).start();
        }
    }
}
public class Counter {
    private static ThreadLocal<Integer> number = new ThreadLocal<Integer>() {
        // 重写这个方法,可以修改“线程变量”的初始值,默认是null
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };
    //计数方法
    public  void count() {
        for( int i= 0;i<= 10;i++) {
            number.set(number.get()+i);
        }
        System.out.println(Thread.currentThread().getName()+ "--"+number.get());
    }
}

执行结果

374d9c083da14f089851c1baf77acd6e.png

2.将全局变量改为成员变量

public  void count(){
         int number = 0;
        for (int i = 0; i <=10 ; i++) {
            number=number+i;
        }
        System.out.println(Thread.currentThread().getName()+ "--"+number);
    }
}

16d3728df0094f1c818f8ffd1d996087.png

2.逻辑混乱多种情况

f9d731a392224da4bff74675e52cb001.png

        由于这里查询的入参带了createDate,如果该学生从第一天到第二天一直没有下课,那么你这儿查询的话由于带了createDate就查询不到该学生的在线数据,在后续的流程中就会重复插入,该学生就会有两条数据,查询的时候就会有数据问题。

4caf1e7f368946c2b8115264874ec45f.png

        对于isOnline参数,上面paramUser中有该参数。不必再进行赋值。这样的好处是参数值保持了一致,降低了复杂度。

e65f4588cff34806b82be3989bdcb654.png

       这里主要是对在线人员进行下线处理,1.如果在这里更新了update_time那么就相当于这个课程班级中的所有学生的最近一次登陆时间都是一致的,并且最近一次登陆时间与实际不符。2.如果where条件上加上了create_date作为条件那么如果过了十二点结束课程,那么所有在线的人就无法进行下线处理了。

3.父子类继承对于this的使用

62cccd4f4d17446dafdd117a7f938f8b.png

        java中继承关系的父子类,相同的方法会被重写。重写之后如果还想继续使用父类的方法,需要通过super关键字去调用父类的方法。

4.关联字段类型不一致导致索引失效

相关博客:(5条消息) 案例12-数据类型不一致导致索引失效_武梓龙_Arvin的博客-CSDN博客

三、总结提升

       拓展我们的知识面,不怕不知道就怕不知道。知识面宽广了在解决问题,思考解决办法才能更丰富维度才会更多。


相关文章
|
8月前
|
安全
dapp互助预约排单系统开发步骤指南/案例设计/规则详细/方案逻辑/源码程序
-Determine the core functions and objectives of the system, understand user needs and expectations.
预约抢单互助系统开发详细功能/需求方案/步骤功能/逻辑项目/源码案例
The development model of appointment and order grabbing mutual assistance system is a widely used development model on mutual assistance service platforms. It adopts a combination of appointment and order grabbing modes, allowing users to make appointments or actively participate in mutual assistanc
|
6月前
|
算法 Perl
技术下午茶:产品经理是如何工作的?如何才算一份好的需求文档?如何设计一个简单的列表,它应该具备哪些基本功能?
技术下午茶:产品经理是如何工作的?如何才算一份好的需求文档?如何设计一个简单的列表,它应该具备哪些基本功能?
65 1
|
6天前
|
数据可视化 API uml
【有奖调研】开发文档功能升级:接口分组更清晰;增加参数中文名
【有奖调研】开发文档功能升级:接口分组更清晰;增加参数中文名
37 0
游戏对接广告看视频系统开发详细规则/方案逻辑/步骤逻辑/规则玩法/源码程序
Advertising location and display method: According to the characteristics of the game interface and scene, choose the appropriate advertising location and display method to ensure that the advertisement naturally integrates into the game and does not affect the player&#39;s game experience.
|
9月前
|
安全
交易所系统开发规则案例丨需求分析丨功能设计丨详细步骤丨源码逻辑
Before developing a digital currency exchange system, a detailed requirement analysis is required. Firstly, it is necessary to clarify the types of digital currencies and trading varieties that the system needs to support. Secondly, it is necessary to determine the user roles and permission manageme
|
9月前
|
新零售 人工智能 供应链
链动2+1开发运营版丨链动2+1系统开发案例详情/方案项目/功能说明/逻辑规则/源码程序
新零售是指传统零售业与互联网技术相结合,通过数字化、数据化和智能化的手段,重新定义和升级传统零售业态的模式和经营方式。
|
10月前
|
SQL 安全 关系型数据库
项目实战典型案例7——在线人员列表逻辑混乱反例
项目实战典型案例7——在线人员列表逻辑混乱反例
121 0
项目实战典型案例7——在线人员列表逻辑混乱反例
|
8月前
|
安全
交易所系统开发详细项目丨案例规则丨方案设计丨步骤需求丨逻辑功能丨源码程序
Requirement analysis and planning: Collaborate with customers to clarify the requirements and goals of the coin exchange system. Understand the customer&#39;s business model, target user group, and currencies to be supported by the exchange, and develop a detailed demand plan.
|
9月前
|
安全 Go 区块链
区块链游戏链游系统开发功能详情丨方案逻辑丨开发项目丨案例分析丨源码规则
 In recent years, with the continuous development of blockchain technology, NFTs (non homogeneous tokens) and DAPPs (decentralized applications) have emerged in the gaming industry.