一:背景介绍
问题一:出现域名不全的情况,和加载到内存的全部变量有关。如果存入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); } }
四:总结
- 在项目开发过程中,对于一些公共变量的使用要慎重,需要考虑是否有并发,以及多线程的情况
- 编写代码的时候,要清楚为什么要这么写