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 */ 017package org.apache.commons.collections4.bag; 018 019import java.util.Set; 020 021import org.apache.commons.collections4.Bag; 022import org.apache.commons.collections4.collection.SynchronizedCollection; 023 024/** 025 * Decorates another {@link Bag} to synchronize its behavior 026 * for a multithreaded environment. 027 * <p> 028 * Methods are synchronized, then forwarded to the decorated bag. 029 * Iterators must be separately synchronized around the loop. 030 * </p> 031 * <p> 032 * This class is Serializable from Commons Collections 3.1. 033 * </p> 034 * 035 * @param <E> the type of elements in this bag 036 * @since 3.0 037 */ 038public class SynchronizedBag<E> extends SynchronizedCollection<E> implements Bag<E> { 039 040 /** 041 * Synchronized Set for the Bag class. 042 */ 043 final class SynchronizedBagSet extends SynchronizedCollection<E> implements Set<E> { 044 /** Serialization version */ 045 private static final long serialVersionUID = 2990565892366827855L; 046 047 /** 048 * Constructs a new instance. 049 * @param set the set to decorate 050 * @param lock the lock to use, shared with the bag 051 */ 052 SynchronizedBagSet(final Set<E> set, final Object lock) { 053 super(set, lock); 054 } 055 } 056 057 /** Serialization version */ 058 private static final long serialVersionUID = 8084674570753837109L; 059 060 /** 061 * Factory method to create a synchronized bag. 062 * 063 * @param <E> the type of the elements in the bag 064 * @param bag the bag to decorate, must not be null 065 * @return a new synchronized Bag 066 * @throws NullPointerException if bag is null 067 * @since 4.0 068 */ 069 public static <E> SynchronizedBag<E> synchronizedBag(final Bag<E> bag) { 070 return new SynchronizedBag<>(bag); 071 } 072 073 /** 074 * Constructor that wraps (not copies). 075 * 076 * @param bag the bag to decorate, must not be null 077 * @throws NullPointerException if bag is null 078 */ 079 protected SynchronizedBag(final Bag<E> bag) { 080 super(bag); 081 } 082 083 /** 084 * Constructor that wraps (not copies). 085 * 086 * @param bag the bag to decorate, must not be null 087 * @param lock the lock to use, must not be null 088 * @throws NullPointerException if bag or lock is null 089 */ 090 protected SynchronizedBag(final Bag<E> bag, final Object lock) { 091 super(bag, lock); 092 } 093 094 @Override 095 public boolean add(final E object, final int count) { 096 synchronized (lock) { 097 return getBag().add(object, count); 098 } 099 } 100 101 @Override 102 public boolean equals(final Object object) { 103 if (object == this) { 104 return true; 105 } 106 synchronized (lock) { 107 return getBag().equals(object); 108 } 109 } 110 111 /** 112 * Gets the bag being decorated. 113 * 114 * @return the decorated bag 115 */ 116 protected Bag<E> getBag() { 117 return (Bag<E>) decorated(); 118 } 119 120 @Override 121 public int getCount(final Object object) { 122 synchronized (lock) { 123 return getBag().getCount(object); 124 } 125 } 126 127 @Override 128 public int hashCode() { 129 synchronized (lock) { 130 return getBag().hashCode(); 131 } 132 } 133 134 @Override 135 public boolean remove(final Object object, final int count) { 136 synchronized (lock) { 137 return getBag().remove(object, count); 138 } 139 } 140 141 @Override 142 public Set<E> uniqueSet() { 143 synchronized (lock) { 144 final Set<E> set = getBag().uniqueSet(); 145 return new SynchronizedBagSet(set, lock); 146 } 147 } 148 149}