【项目实战典型案例】15.登录之后我加入的课程调用接口报错

简介: 【项目实战典型案例】15.登录之后我加入的课程调用接口报错

一:背景介绍

问题一:出现域名不全的情况,和加载到内存的全部变量有关。如果存入redis的值一旦错误,一天内都会出现这样的情况

问题二:每一次登录都会重新创建一个对象,放到公共变量中,如果遇到了并发,这里的对象将会被大量的创建,然后上一个对象会失去引用,等待垃圾回收器回收,从而会导致cpu飙升

二:问题复现

数据混乱现象复现

计算类

public class ThreadTest {
    List<String> threadList = new ArrayList<>();
    public void ThreadList1(){
        threadList = new ArrayList<>();
        threadList.add("1");
        threadList.add("2");
        threadList.add("3");
        threadList.add("4");
        System.out.println("ThreadList1"+threadList);
    }
    public void ThreadList2(){
        threadList = new ArrayList<>();
        threadList.add("a");
        threadList.add("b");
        threadList.add("c");
        threadList.add("d");
        //看一下list里有什么
        System.out.println("ThreadList2"+threadList);
    }
}

客户端类

public class Client {
    public static void main(String[] args) {
        ThreadTest threadTest = new ThreadTest();
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    threadTest.ThreadList1();
                    threadTest.ThreadList2();
                }
            });
            thread.start();
        }
    }
}

实现结果

出现了数据混乱的情况

三:优化过程

问题一

使用ThreadLocal

计算类

public class ThreadTest {
    private static ThreadLocal<List<String>> threadList = new ThreadLocal<List<String>>(){
        @Override
        public List<String> initialValue(){
            return new ArrayList<String>();
        }
    };
    public void ThreadList1(){
        threadList.get().add("1");
        threadList.get().add("2");
        threadList.get().add("3");
        threadList.get().add("4");
        System.out.println("ThreadList1"+threadList.get());
    }
}

实现效果

使用synchronized进行

synchronized保证方法某一时刻只有一个线程去执行,从而保证线程安全性

synchronized可以修饰方法,对象实例,某个类,代码块

public class ThreadTest {
    List<String> threadList = new ArrayList<>();
    public synchronized void ThreadList2(){
        threadList = new ArrayList<>();
        threadList.add("a");
        threadList.add("b");
        threadList.add("c");
        threadList.add("d");
        //看一下list里有什么
        System.out.println("ThreadList2"+threadList);
    }
}

问题二

调用removeALL()方法

public class ThreadTest {
    List<String> threadList = new ArrayList<>();
    public synchronized void ThreadList2(){
        threadList = new ArrayList<>();
        threadList.add("a");
        threadList.add("b");
        threadList.add("c");
        threadList.add("d");
        //看一下list里有什么
        System.out.println("ThreadList2"+threadList);
        threadList.removeAll(threadList);
    }
}

四:总结

  1. 在项目开发过程中,对于一些公共变量的使用要慎重,需要考虑是否有并发,以及多线程的情况
  2. 编写代码的时候,要清楚为什么要这么写


相关文章
|
前端开发
前端学习笔记202305学习笔记第二十二天-登录方法封装和404之3
前端学习笔记202305学习笔记第二十二天-登录方法封装和404之3
55 0
|
BI 定位技术 Python
SWMM从入门到实践教程 04 快速入门案例的模拟执行
在左侧双击Options中的Dates,即可弹出时间的设置。此处为了教学,建议仅模拟6个小时,加快结果的生成。实际项目中,可以根据需求对指定场次的降雨时常进行模拟,并注意这个时常一定不低于降雨时常(我们的雨量计设置了2小时降雨,所有66个小时的模拟也是合理的)。
|
前端开发
前端学习笔记202305学习笔记第二十二天-登录页进阶验证2
前端学习笔记202305学习笔记第二十二天-登录页进阶验证2
68 0
|
前端开发
前端学习笔记202305学习笔记第二十二天-登录页进阶验证1
前端学习笔记202305学习笔记第二十二天-登录页进阶验证1
52 0
|
前端开发
前端学习笔记202305学习笔记第二十二天-登录方法封装和404之1
前端学习笔记202305学习笔记第二十二天-登录方法封装和404之1
57 0
|
前端开发
前端学习笔记202305学习笔记第二十二天-登录方法封装和404之2
前端学习笔记202305学习笔记第二十二天-登录方法封装和404之2
74 0
|
安全 NoSQL Java
项目实战15—登录之后我加入的课程调用接口报错
项目实战15—登录之后我加入的课程调用接口报错
92 0
|
存储 缓存 前端开发
项目实战典型案例13——学情页面逻辑问题
项目实战典型案例13——学情页面逻辑问题
70 0
|
存储 缓存 前端开发
【项目实战典型案例】13.学情页面逻辑问题
【项目实战典型案例】13.学情页面逻辑问题
|
负载均衡 前端开发 Java
项目实战典型案例3——fegin调用404情况
项目实战典型案例3——fegin调用404情况
706 0