View Javadoc

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