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 * @since 3.0 034 * @version $Id: SynchronizedBag.html 972421 2015-11-14 20:00:04Z tn $ 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 IllegalArgumentException if bag is null 048 * @since 4.0 049 */ 050 public static <E> SynchronizedBag<E> synchronizedBag(final Bag<E> bag) { 051 return new SynchronizedBag<E>(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 IllegalArgumentException 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 IllegalArgumentException if bag 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 //----------------------------------------------------------------------- 086 087 public boolean add(final E object, final int count) { 088 synchronized (lock) { 089 return getBag().add(object, count); 090 } 091 } 092 093 public boolean remove(final Object object, final int count) { 094 synchronized (lock) { 095 return getBag().remove(object, count); 096 } 097 } 098 099 public Set<E> uniqueSet() { 100 synchronized (lock) { 101 final Set<E> set = getBag().uniqueSet(); 102 return new SynchronizedBagSet(set, lock); 103 } 104 } 105 106 public int getCount(final Object object) { 107 synchronized (lock) { 108 return getBag().getCount(object); 109 } 110 } 111 112 //----------------------------------------------------------------------- 113 /** 114 * Synchronized Set for the Bag class. 115 */ 116 class SynchronizedBagSet extends SynchronizedCollection<E> implements Set<E> { 117 /** Serialization version */ 118 private static final long serialVersionUID = 2990565892366827855L; 119 120 /** 121 * Constructor. 122 * @param set the set to decorate 123 * @param lock the lock to use, shared with the bag 124 */ 125 SynchronizedBagSet(final Set<E> set, final Object lock) { 126 super(set, lock); 127 } 128 } 129 130}