文章目录
对象未完成初始化就把对象提供给外界–构造方法中新建线程
- 对象未完成初始化就把对象提供给外界--构造方法中新建线程
如下的代码 ,演示了 构造方法中新建线程 . 例如给map赋值. 之后在main方法调用中, 尝试获取map中,对应key的值
package com.thread.background;
import java.util.HashMap;
import java.util.Map;
/**
* 类名称:ConstructNewThread
* 类描述: 构造方法中新建线程
*
* @author: https://javaweixin6.blog.csdn.net/
* 创建时间:2020/9/1 21:40
* Version 1.0
*/
public class ConstructNewThread {
//定义一个private私有变量
private Map states ;
public ConstructNewThread() {
//在子线程中, 对map进行赋值
new Thread(()->{
states = new HashMap();
states.put("1","a");
states.put("2","b");
states.put("3","c");
}).start();
}
//对象逸出 返回了一个私有变量
public Map getStates() {
return states;
}
public static void main(String[] args) throws InterruptedException {
ConstructNewThread re = new ConstructNewThread();
Map states = re.getStates();
//map中获取值
System.out.println(states.get("1"));
}
}
此时运行程序, 得到的结果却是空指针. 主要的原因是, map中赋值, 是新建立的线程. 而在执行re.getStates()
的时候, 此时子线程还没获得cpu的执行权,导致map中是空的值. 尝试获取值就是null . 修改代码, main线程中休眠10ms ,让出cpu 的资源去初始化map 的值, 这个时候运行程序,就没有报错了. 成功的获得了值. 因此这样在构造方法中新建线程也是造成线程不安全的原因之一.
此种情况可以用工厂模式解决. 后续的文章中会写到.
虽然在开发中不会在构造方法中去新建立线程 ,但是获取某个资源的时候, 例如线程池的引用或者是数据库的连接池, 在获取连接池的时候, 底层的代码是会去新建立线程以加快速度的. 这样是隐含的在构造方法中新开线程,就容易造成线程安全问题.