1. /*
  2. * Copyright 2003-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections.collection;
  17. import java.io.Serializable;
  18. import java.util.Collection;
  19. import java.util.Iterator;
  20. /**
  21. * Decorates another <code>Collection</code> to synchronize its behaviour
  22. * for a multi-threaded environment.
  23. * <p>
  24. * Iterators must be manually synchronized:
  25. * <pre>
  26. * synchronized (coll) {
  27. * Iterator it = coll.iterator();
  28. * // do stuff with iterator
  29. * }
  30. * </pre>
  31. * <p>
  32. * This class is Serializable from Commons Collections 3.1.
  33. *
  34. * @since Commons Collections 3.0
  35. * @version $Revision: 1.7 $ $Date: 2004/06/03 22:02:13 $
  36. *
  37. * @author Stephen Colebourne
  38. */
  39. public class SynchronizedCollection implements Collection, Serializable {
  40. /** Serialization version */
  41. private static final long serialVersionUID = 2412805092710877986L;
  42. /** The collection to decorate */
  43. protected final Collection collection;
  44. /** The object to lock on, needed for List/SortedSet views */
  45. protected final Object lock;
  46. /**
  47. * Factory method to create a synchronized collection.
  48. *
  49. * @param coll the collection to decorate, must not be null
  50. * @return a new synchronized collection
  51. * @throws IllegalArgumentException if collection is null
  52. */
  53. public static Collection decorate(Collection coll) {
  54. return new SynchronizedCollection(coll);
  55. }
  56. //-----------------------------------------------------------------------
  57. /**
  58. * Constructor that wraps (not copies).
  59. *
  60. * @param collection the collection to decorate, must not be null
  61. * @throws IllegalArgumentException if the collection is null
  62. */
  63. protected SynchronizedCollection(Collection collection) {
  64. if (collection == null) {
  65. throw new IllegalArgumentException("Collection must not be null");
  66. }
  67. this.collection = collection;
  68. this.lock = this;
  69. }
  70. /**
  71. * Constructor that wraps (not copies).
  72. *
  73. * @param collection the collection to decorate, must not be null
  74. * @param lock the lock object to use, must not be null
  75. * @throws IllegalArgumentException if the collection is null
  76. */
  77. protected SynchronizedCollection(Collection collection, Object lock) {
  78. if (collection == null) {
  79. throw new IllegalArgumentException("Collection must not be null");
  80. }
  81. this.collection = collection;
  82. this.lock = lock;
  83. }
  84. //-----------------------------------------------------------------------
  85. public boolean add(Object object) {
  86. synchronized (lock) {
  87. return collection.add(object);
  88. }
  89. }
  90. public boolean addAll(Collection coll) {
  91. synchronized (lock) {
  92. return collection.addAll(coll);
  93. }
  94. }
  95. public void clear() {
  96. synchronized (lock) {
  97. collection.clear();
  98. }
  99. }
  100. public boolean contains(Object object) {
  101. synchronized (lock) {
  102. return collection.contains(object);
  103. }
  104. }
  105. public boolean containsAll(Collection coll) {
  106. synchronized (lock) {
  107. return collection.containsAll(coll);
  108. }
  109. }
  110. public boolean isEmpty() {
  111. synchronized (lock) {
  112. return collection.isEmpty();
  113. }
  114. }
  115. /**
  116. * Iterators must be manually synchronized.
  117. * <pre>
  118. * synchronized (coll) {
  119. * Iterator it = coll.iterator();
  120. * // do stuff with iterator
  121. * }
  122. *
  123. * @return an iterator that must be manually synchronized on the collection
  124. */
  125. public Iterator iterator() {
  126. return collection.iterator();
  127. }
  128. public Object[] toArray() {
  129. synchronized (lock) {
  130. return collection.toArray();
  131. }
  132. }
  133. public Object[] toArray(Object[] object) {
  134. synchronized (lock) {
  135. return collection.toArray(object);
  136. }
  137. }
  138. public boolean remove(Object object) {
  139. synchronized (lock) {
  140. return collection.remove(object);
  141. }
  142. }
  143. public boolean removeAll(Collection coll) {
  144. synchronized (lock) {
  145. return collection.removeAll(coll);
  146. }
  147. }
  148. public boolean retainAll(Collection coll) {
  149. synchronized (lock) {
  150. return collection.retainAll(coll);
  151. }
  152. }
  153. public int size() {
  154. synchronized (lock) {
  155. return collection.size();
  156. }
  157. }
  158. public boolean equals(Object object) {
  159. synchronized (lock) {
  160. if (object == this) {
  161. return true;
  162. }
  163. return collection.equals(object);
  164. }
  165. }
  166. public int hashCode() {
  167. synchronized (lock) {
  168. return collection.hashCode();
  169. }
  170. }
  171. public String toString() {
  172. synchronized (lock) {
  173. return collection.toString();
  174. }
  175. }
  176. }