Java多线程 对象未完成初始化就把对象提供给外界--构造方法中新建线程

对象未完成初始化就把对象提供给外界–构造方法中新建线程

如下的代码 ,演示了 构造方法中新建线程 . 例如给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<String,String> states ;

    public ConstructNewThread() {

        //在子线程中, 对map进行赋值
        new Thread(()->{
            states = new HashMap<>();
            states.put("1","a");
            states.put("2","b");
            states.put("3","c");

        }).start();
    }
    //对象逸出  返回了一个私有变量
    public Map<String, String> getStates() {
        return states;
    }

    public static void main(String[] args) throws InterruptedException {
        ConstructNewThread re = new ConstructNewThread();

        Map<String, String> states = re.getStates();

        //map中获取值
        System.out.println(states.get("1"));
    }
}

此时运行程序, 得到的结果却是空指针.
主要的原因是, map中赋值, 是新建立的线程. 而在执行re.getStates()的时候, 此时子线程还没获得cpu的执行权,导致map中是空的值. 尝试获取值就是null .

修改代码, main线程中休眠10ms ,让出cpu 的资源去初始化map 的值, 这个时候运行程序,就没有报错了. 成功的获得了值. 因此这样在构造方法中新建线程也是造成线程不安全的原因之一.

此种情况可以用工厂模式解决. 后续的文章中会写到.

虽然在开发中不会在构造方法中去新建立线程 ,但是获取某个资源的时候, 例如线程池的引用或者是数据库的连接池, 在获取连接池的时候, 底层的代码是会去新建立线程以加快速度的. 这样是隐含的在构造方法中新开线程,就容易造成线程安全问题.

猜你喜欢

转载自blog.csdn.net/qq_33229669/article/details/108351757