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
-
the
setATeamMembersmethod is called only once, by spring when it is creating theATeamEpisodebean -
the
initmethod is called by spring (init-method) after #1 -
the
ATeamMemberclass is immutable-
Do I need to declare the
teamMembersvolatileor 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();
}
}
}
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.