Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread safety implications of Spring DI

In my contrived example, what are the implications for thread safety with regard to the list of teamMembers?

Can I rely on the state of the list as seen by the run() method to be consistent?

Assuming

  1. the setATeamMembers method is called only once, by spring when it is creating the ATeamEpisode bean

  2. the init method is called by spring (init-method) after #1

  3. the ATeamMember class is immutable

    • Do I need to declare the teamMembers volatile or similar?

    • Are there any other hideous problems with this approach that I'm overlooking?

Apologies if this is obvious, or a clear failure to rtfm

Thanks and regards

Ed

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();
        }
    }
}
like image 350
user591948 Avatar asked Oct 08 '12 11:10

user591948


People also ask

Does spring provide thread safety?

No spring object is not thread safe . You have to manage it. For scope thread different service bean is created for every new thread request to service.

Is spring dependency injection thread-safe?

You should not worry about thread safety of the dependency injection, Spring does (most likely, spring is going to use just one thread to inject all the dependencies).

How do I make my spring controller thread-safe?

So YES, Spring MVC classes must be thread safe. You can do this by playing with different scopes for your class instance fields or just having local variables instead. Failing that, you'll need to add appropriate synchronization around critical sections in your code.

Why spring singleton is not thread-safe?

If there is any global variable defined the singleton class then it will not be thread safe because if multiple thread share the singleton object and execute the method which can updates the global variable it will not be thread safe.


1 Answers

If, as you say, setATeamMembers is called only once, and no other part of your code either replaces this collection, then there is no point in making it volatile. Volatile indicates that a member can be written by different threads.

Considering no part of your code seems to be updating this collection either, you might want to consider making the collection explicitly unmodifiable, for instance by using Collections.unmodifiableList(). This makes it clear to you, and others, that this collection won't be modified, and will throw a big fat exception in your face if you try to modify it regardless.

Spring's lazy initialization is, AFAIR, thread safe.

like image 155
Nim Avatar answered Nov 16 '22 03:11

Nim