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.list;
  17. import java.util.Collection;
  18. import java.util.List;
  19. import java.util.ListIterator;
  20. import org.apache.commons.collections.collection.SynchronizedCollection;
  21. /**
  22. * Decorates another <code>List</code> to synchronize its behaviour
  23. * for a multi-threaded environment.
  24. * <p>
  25. * Methods are synchronized, then forwarded to the decorated list.
  26. * <p>
  27. * This class is Serializable from Commons Collections 3.1.
  28. *
  29. * @since Commons Collections 3.0
  30. * @version $Revision: 1.5 $ $Date: 2004/06/03 22:02:13 $
  31. *
  32. * @author Stephen Colebourne
  33. */
  34. public class SynchronizedList extends SynchronizedCollection implements List {
  35. /** Serialization version */
  36. private static final long serialVersionUID = -1403835447328619437L;
  37. /**
  38. * Factory method to create a synchronized list.
  39. *
  40. * @param list the list to decorate, must not be null
  41. * @throws IllegalArgumentException if list is null
  42. */
  43. public static List decorate(List list) {
  44. return new SynchronizedList(list);
  45. }
  46. //-----------------------------------------------------------------------
  47. /**
  48. * Constructor that wraps (not copies).
  49. *
  50. * @param list the list to decorate, must not be null
  51. * @throws IllegalArgumentException if list is null
  52. */
  53. protected SynchronizedList(List list) {
  54. super(list);
  55. }
  56. /**
  57. * Constructor that wraps (not copies).
  58. *
  59. * @param list the list to decorate, must not be null
  60. * @param lock the lock to use, must not be null
  61. * @throws IllegalArgumentException if list is null
  62. */
  63. protected SynchronizedList(List list, Object lock) {
  64. super(list, lock);
  65. }
  66. /**
  67. * Gets the decorated list.
  68. *
  69. * @return the decorated list
  70. */
  71. protected List getList() {
  72. return (List) collection;
  73. }
  74. //-----------------------------------------------------------------------
  75. public void add(int index, Object object) {
  76. synchronized (lock) {
  77. getList().add(index, object);
  78. }
  79. }
  80. public boolean addAll(int index, Collection coll) {
  81. synchronized (lock) {
  82. return getList().addAll(index, coll);
  83. }
  84. }
  85. public Object get(int index) {
  86. synchronized (lock) {
  87. return getList().get(index);
  88. }
  89. }
  90. public int indexOf(Object object) {
  91. synchronized (lock) {
  92. return getList().indexOf(object);
  93. }
  94. }
  95. public int lastIndexOf(Object object) {
  96. synchronized (lock) {
  97. return getList().lastIndexOf(object);
  98. }
  99. }
  100. /**
  101. * Iterators must be manually synchronized.
  102. * <pre>
  103. * synchronized (coll) {
  104. * ListIterator it = coll.listIterator();
  105. * // do stuff with iterator
  106. * }
  107. *
  108. * @return an iterator that must be manually synchronized on the collection
  109. */
  110. public ListIterator listIterator() {
  111. return getList().listIterator();
  112. }
  113. /**
  114. * Iterators must be manually synchronized.
  115. * <pre>
  116. * synchronized (coll) {
  117. * ListIterator it = coll.listIterator(3);
  118. * // do stuff with iterator
  119. * }
  120. *
  121. * @return an iterator that must be manually synchronized on the collection
  122. */
  123. public ListIterator listIterator(int index) {
  124. return getList().listIterator(index);
  125. }
  126. public Object remove(int index) {
  127. synchronized (lock) {
  128. return getList().remove(index);
  129. }
  130. }
  131. public Object set(int index, Object object) {
  132. synchronized (lock) {
  133. return getList().set(index, object);
  134. }
  135. }
  136. public List subList(int fromIndex, int toIndex) {
  137. synchronized (lock) {
  138. List list = getList().subList(fromIndex, toIndex);
  139. // the lock is passed into the constructor here to ensure that the sublist is
  140. // synchronized on the same lock as the parent list
  141. return new SynchronizedList(list, lock);
  142. }
  143. }
  144. }