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