001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.collections.list; 018 019 import java.util.Collection; 020 import java.util.List; 021 import java.util.ListIterator; 022 023 import org.apache.commons.collections.collection.SynchronizedCollection; 024 025 /** 026 * Decorates another <code>List</code> to synchronize its behaviour 027 * for a multi-threaded environment. 028 * <p> 029 * Methods are synchronized, then forwarded to the decorated list. 030 * <p> 031 * This class is Serializable from Commons Collections 3.1. 032 * 033 * @since Commons Collections 3.0 034 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $ 035 * 036 * @author Stephen Colebourne 037 */ 038 public class SynchronizedList extends SynchronizedCollection implements List { 039 040 /** Serialization version */ 041 private static final long serialVersionUID = -1403835447328619437L; 042 043 /** 044 * Factory method to create a synchronized list. 045 * 046 * @param list the list to decorate, must not be null 047 * @throws IllegalArgumentException if list is null 048 */ 049 public static List decorate(List list) { 050 return new SynchronizedList(list); 051 } 052 053 //----------------------------------------------------------------------- 054 /** 055 * Constructor that wraps (not copies). 056 * 057 * @param list the list to decorate, must not be null 058 * @throws IllegalArgumentException if list is null 059 */ 060 protected SynchronizedList(List list) { 061 super(list); 062 } 063 064 /** 065 * Constructor that wraps (not copies). 066 * 067 * @param list the list to decorate, must not be null 068 * @param lock the lock to use, must not be null 069 * @throws IllegalArgumentException if list is null 070 */ 071 protected SynchronizedList(List list, Object lock) { 072 super(list, lock); 073 } 074 075 /** 076 * Gets the decorated list. 077 * 078 * @return the decorated list 079 */ 080 protected List getList() { 081 return (List) collection; 082 } 083 084 //----------------------------------------------------------------------- 085 public void add(int index, Object object) { 086 synchronized (lock) { 087 getList().add(index, object); 088 } 089 } 090 091 public boolean addAll(int index, Collection coll) { 092 synchronized (lock) { 093 return getList().addAll(index, coll); 094 } 095 } 096 097 public Object get(int index) { 098 synchronized (lock) { 099 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 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 listIterator(int index) { 140 return getList().listIterator(index); 141 } 142 143 public Object remove(int index) { 144 synchronized (lock) { 145 return getList().remove(index); 146 } 147 } 148 149 public Object set(int index, Object object) { 150 synchronized (lock) { 151 return getList().set(index, object); 152 } 153 } 154 155 public List subList(int fromIndex, int toIndex) { 156 synchronized (lock) { 157 List 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(list, lock); 161 } 162 } 163 164 }