【项目实战典型案例】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. 编写代码的时候,要清楚为什么要这么写


相关文章
|
算法 区块链 数据安全/隐私保护
[区块链] 密码学——椭圆曲线密码算法(ECC)
  今天在学椭圆曲线密码(Elliptic Curve Cryptography,ECC)算法,自己手里缺少介绍该算法的专业书籍,故在网上查了很多博文与书籍,但是大多数博客写的真的是。。。你懂的。。。真不愧是 ‘天下文章一大抄’ 啊! 雷同不说,关键是介绍的都不是很清楚,是我在阅读过程中、产生的很多...
3215 0
|
Linux Python
bypy:使用Linux命令行上传及下载百度云盘文件(远程服务器大文件传输必备)
bypy:使用Linux命令行上传及下载百度云盘文件(远程服务器大文件传输必备)
bypy:使用Linux命令行上传及下载百度云盘文件(远程服务器大文件传输必备)
|
存储 JSON API
深入解析RESTful API设计原则与实践
【9月更文挑战第21天】在数字化时代,后端开发不仅仅是编写代码那么简单。它关乎于如何高效地连接不同的系统和服务。RESTful API作为一套广泛采用的设计准则,提供了一种优雅的解决方案来简化网络服务的开发。本文将带你深入了解RESTful API的核心设计原则,并通过实际代码示例展示如何将这些原则应用于日常的后端开发工作中。
|
机器学习/深度学习 人工智能 编解码
国际奥委会采用阿里云AI云技术修复奥运历史影像
国际奥委会采用阿里云AI云技术修复奥运历史影像
324 4
|
JSON NoSQL 前端开发
微信扫码登录的技术实现思考
微信扫码登录是很常见的技术,曾经在一次面试当中,面试官就曾问过微信扫码登录的实现思路,这次,以微信读书网页版扫码登录为例子,聊聊我对它技术实现思路一些思考。
326 0
|
缓存 Linux 数据库
linux系统中buff/cache占用过高?不明白为何过高?
linux系统中buff/cache占用过高?不明白为何过高?
2874 1
|
数据可视化 API 开发者
直方图(histogram)| 学习笔记
快速学习直方图(histogram)
829 0
直方图(histogram)| 学习笔记
|
SQL 存储 关系型数据库
探索MySQL-Cluster奥秘系列之SQL节点(3)
在上一小节中,我们对MySQL-Cluster集群的管理节点进行了介绍,那么接下来,我们继续进行讲解,来了解下MySQL-Cluster集群的SQL节点的作用和功能。
249 0