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.bag;
018
019 import java.util.Set;
020
021 import org.apache.commons.collections.Bag;
022 import org.apache.commons.collections.collection.SynchronizedCollection;
023 import org.apache.commons.collections.set.SynchronizedSet;
024
025 /**
026 * Decorates another <code>Bag</code> to synchronize its behaviour
027 * for a multi-threaded environment.
028 * <p>
029 * Methods are synchronized, then forwarded to the decorated bag.
030 * Iterators must be separately synchronized around the loop.
031 * <p>
032 * This class is Serializable from Commons Collections 3.1.
033 *
034 * @since Commons Collections 3.0
035 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
036 *
037 * @author Stephen Colebourne
038 */
039 public class SynchronizedBag
040 extends SynchronizedCollection implements Bag {
041
042 /** Serialization version */
043 private static final long serialVersionUID = 8084674570753837109L;
044
045 /**
046 * Factory method to create a synchronized bag.
047 *
048 * @param bag the bag to decorate, must not be null
049 * @return a new synchronized Bag
050 * @throws IllegalArgumentException if bag is null
051 */
052 public static Bag decorate(Bag bag) {
053 return new SynchronizedBag(bag);
054 }
055
056 //-----------------------------------------------------------------------
057 /**
058 * Constructor that wraps (not copies).
059 *
060 * @param bag the bag to decorate, must not be null
061 * @throws IllegalArgumentException if bag is null
062 */
063 protected SynchronizedBag(Bag bag) {
064 super(bag);
065 }
066
067 /**
068 * Constructor that wraps (not copies).
069 *
070 * @param bag the bag to decorate, must not be null
071 * @param lock the lock to use, must not be null
072 * @throws IllegalArgumentException if bag is null
073 */
074 protected SynchronizedBag(Bag bag, Object lock) {
075 super(bag, lock);
076 }
077
078 /**
079 * Gets the bag being decorated.
080 *
081 * @return the decorated bag
082 */
083 protected Bag getBag() {
084 return (Bag) collection;
085 }
086
087 //-----------------------------------------------------------------------
088 public boolean add(Object object, int count) {
089 synchronized (lock) {
090 return getBag().add(object, count);
091 }
092 }
093
094 public boolean remove(Object object, int count) {
095 synchronized (lock) {
096 return getBag().remove(object, count);
097 }
098 }
099
100 public Set uniqueSet() {
101 synchronized (lock) {
102 Set set = getBag().uniqueSet();
103 return new SynchronizedBagSet(set, lock);
104 }
105 }
106
107 public int getCount(Object object) {
108 synchronized (lock) {
109 return getBag().getCount(object);
110 }
111 }
112
113 //-----------------------------------------------------------------------
114 /**
115 * Synchronized Set for the Bag class.
116 */
117 class SynchronizedBagSet extends SynchronizedSet {
118 /**
119 * Constructor.
120 * @param set the set to decorate
121 * @param lock the lock to use, shared with the bag
122 */
123 SynchronizedBagSet(Set set, Object lock) {
124 super(set, lock);
125 }
126 }
127
128 }