2323 */
2424
2525import java .util .Collections ;
26+ import java .util .Iterator ;
2627import java .util .List ;
2728import java .util .function .Supplier ;
2829
3637 */
3738public class AbstractHost implements Host {
3839
40+ private final Object lock = new Object ();
41+
3942 protected int line ;
4043
4144 // avoid creating an empty list for each element, when it is not used
4245 // use lazy instantiation (in addTag) instead
43- protected List <Tag > mTagList = null ;
46+ protected ConcurrentList <Tag > mTagList = null ;
4447
4548 /**
4649 * Get the {@link List} of {@link Tag Tags} on {@code this} {@link Host}. This list should not be modified!
@@ -59,25 +62,14 @@ public List<Tag> getTags() {
5962 */
6063 @ Override
6164 public void removeTag (String aName ) {
62- int tagIndex = searchForTag (aName );
63- if (tagIndex != -1 ) {
64- mTagList .remove (tagIndex );
65- }
66- }
67-
68- /**
69- * Search for {@link Tag} named {@code aName}.
70- */
71- private int searchForTag (String aName ) {
72- if (mTagList != null ) {
73- for (int i = 0 ; i < mTagList .size (); i ++) {
74- Tag tag = mTagList .get (i );
75- if (tag != null && tag .getName ().equals (aName )) {
76- return i ;
77- }
65+ Iterator <Tag > it = mTagList .iterator ();
66+ while (it .hasNext ()) {
67+ Tag tag = it .next ();
68+ if (tag != null && tag .getName ().equals (aName )) {
69+ it .remove ();
70+ break ;
7871 }
7972 }
80- return -1 ;
8173 }
8274
8375 /**
@@ -91,8 +83,7 @@ private int searchForTag(String aName) {
9183 @ Override
9284 public Tag getTag (String aName ) {
9385 if (mTagList != null ) {
94- for (int i = 0 ; i < mTagList .size (); i ++) {
95- Tag tag = mTagList .get (i );
86+ for (Tag tag : mTagList ) {
9687 if (tag != null && tag .getName ().equals (aName )) {
9788 return tag ;
9889 }
@@ -110,7 +101,14 @@ public Tag getTag(String aName) {
110101 */
111102 @ Override
112103 public boolean hasTag (String aName ) {
113- return (searchForTag (aName ) != -1 );
104+ if (mTagList != null ) {
105+ for (Tag tag : mTagList ) {
106+ if (tag != null && tag .getName ().equals (aName )) {
107+ return true ;
108+ }
109+ }
110+ }
111+ return false ;
114112 }
115113
116114 /**
@@ -120,10 +118,22 @@ public boolean hasTag(String aName) {
120118 */
121119 @ Override
122120 public void addTag (Tag t ) {
123- if (mTagList == null ) {
124- mTagList = new ConcurrentList <Tag >();
121+ List <Tag > l = getOrCreateTagList ();
122+ l .add (t );
123+ }
124+
125+ private List <Tag > getOrCreateTagList () {
126+ ConcurrentList <Tag > l = mTagList ;
127+ if (l == null ) {
128+ synchronized (lock ) {
129+ l = mTagList ;
130+ if (l == null ) {
131+ l = new ConcurrentList <Tag >();
132+ mTagList = l ;
133+ }
134+ }
125135 }
126- mTagList . add ( t ) ;
136+ return l ;
127137 }
128138
129139 /**
@@ -143,10 +153,7 @@ public void removeAllTags() {
143153 public void addAllTagsOf (Host h ) {
144154 List <Tag > tags = h .getTags ();
145155 if (!tags .isEmpty ()) {
146- if (mTagList == null ) {
147- mTagList = new ConcurrentList <Tag >();
148- }
149- mTagList .addAll (tags );
156+ getOrCreateTagList ().addAll (tags );
150157 }
151158 }
152159
@@ -174,11 +181,9 @@ public int getJavaSourceStartColumnNumber() {
174181
175182 @ Override
176183 public Tag getOrComputeTag (String aName , Supplier <Tag > supplier ) {
177- if (mTagList == null ) {
178- mTagList = new ConcurrentList <Tag >();
179- }
180- for (int i = 0 ; i < mTagList .size (); i ++) {
181- Tag p = mTagList .get (i );
184+ List <Tag > l = getOrCreateTagList ();
185+
186+ for (Tag p : l ) {
182187 if (p != null && p .getName ().equals (aName )) {
183188 return p ;
184189 }
0 commit comments