java - Spring DI 的线程安全影响

标签 java spring dependency-injection thread-safety

在我设计的示例中,关于 teamMembers 列表的线程安全有何影响?

我能否依赖 run() 方法看到的列表状态保持一致?

假设

  1. setATeamMembers 方法仅在创建 ATeamEpisode bean 时由 spring 调用一次

  2. init方法在#1之后被spring(init-method)调用

  3. ATeamMember 类是不可变的

    • 我是否需要声明 teamMembers volatile 或类似的?

    • 我的这种方法还有其他可怕的问题吗 俯瞰?

如果这是显而易见的,或者 rtfm 的明显失败,我们深表歉意

感谢和问候

埃德

package aTeam;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class ATeamEpisode implements Runnable{

    private List<ATeamMember> teamMembers;

    /* DI by spring */
    public void setATeamMembers(List<ATeamMember> teamMembers){
        this.teamMembers = new ArrayList<ATeamMember>(teamMembers);    
    }

    private Thread skirmishThread;

    public synchronized void init(){
        System.out.println("Starting skirmish");
        destroy();
        (skirmishThread = new Thread(this,"SkirmishThread")).start();
    }
    public synchronized void destroy(){
        if (skirmishThread != null){
            skirmishThread.interrupt();
            skirmishThread=null;
        }
    }

    private void firesWildlyIntoTheAir(ATeamMember teamMember){
        System.out.println(teamMember.getName()+" sprays the sky..");
    }

    @Override
    public void run() {
        try {
            Random rnd = new Random();
            while(! Thread.interrupted()){
                firesWildlyIntoTheAir(teamMembers.get(rnd.nextInt(teamMembers.size())));
                Thread.sleep(1000 * rnd.nextInt(5));
            }
        } catch (InterruptedException e) {
            System.out.println("End of skirmish");
            /* edit as per Adam's suggestion */
           // Thread.currentThread().interrupt();
        }
    }
}

最佳答案

如果像您所说的那样,setATeamMembers 只被调用一次,并且您的代码中没有任何其他部分会替换此集合,那么就没有必要将其设置为 volatile 集合。 Volatile 表示一个成员可以被不同的线程写入

考虑到您的代码似乎也没有更新此集合,您可能需要考虑使集合显式不可修改,例如使用 Collections.unmodifiableList()。这让你和其他人清楚地知道,这个集合不会被修改,如果你无论如何都试图修改它,将会在你面前抛出一个巨大的异常。

Spring 的惰性初始化是,AFAIR,线程安全的。

关于java - Spring DI 的线程安全影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12781095/

相关文章:

java - 在 Java 中运行命令行

java - 什么是NullPointerException,我该如何解决?

java - Spring Data Jpa 查询返回的对象具有空值

java - 没有设置数据源就无法启动 spring boot 应用程序

python - 将 Python 模块作为参数传递是一个好习惯吗

c# - 使用 .Net 类库进行依赖注入(inject)?

java - 实例化 org.springframework.beans.propertyeditors.StringTrimmerEditor 的 bean 时出错

Java String 类实习

Spring Integration - 消息驱动 channel 适配器 - 转换器错误句柄、原始消息

c# - 问题解决与 Unity 的依赖关系