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.math3.stat.descriptive;
018    
019    import org.apache.commons.math3.exception.MathIllegalArgumentException;
020    import org.apache.commons.math3.exception.NullArgumentException;
021    import org.apache.commons.math3.util.MathUtils;
022    
023    /**
024     * Implementation of
025     * {@link org.apache.commons.math3.stat.descriptive.DescriptiveStatistics} that
026     * is safe to use in a multithreaded environment.  Multiple threads can safely
027     * operate on a single instance without causing runtime exceptions due to race
028     * conditions.  In effect, this implementation makes modification and access
029     * methods atomic operations for a single instance.  That is to say, as one
030     * thread is computing a statistic from the instance, no other thread can modify
031     * the instance nor compute another statistic.
032     *
033     * @since 1.2
034     * @version $Id: SynchronizedDescriptiveStatistics.java 1416643 2012-12-03 19:37:14Z tn $
035     */
036    public class SynchronizedDescriptiveStatistics extends DescriptiveStatistics {
037    
038        /** Serialization UID */
039        private static final long serialVersionUID = 1L;
040    
041        /**
042         * Construct an instance with infinite window
043         */
044        public SynchronizedDescriptiveStatistics() {
045            // no try-catch or advertized IAE because arg is valid
046            this(INFINITE_WINDOW);
047        }
048    
049        /**
050         * Construct an instance with finite window
051         * @param window the finite window size.
052         * @throws MathIllegalArgumentException if window size is less than 1 but
053         * not equal to {@link #INFINITE_WINDOW}
054         */
055        public SynchronizedDescriptiveStatistics(int window) throws MathIllegalArgumentException {
056            super(window);
057        }
058    
059        /**
060         * A copy constructor. Creates a deep-copy of the {@code original}.
061         *
062         * @param original the {@code SynchronizedDescriptiveStatistics} instance to copy
063         * @throws NullArgumentException if original is null
064         */
065        public SynchronizedDescriptiveStatistics(SynchronizedDescriptiveStatistics original)
066        throws NullArgumentException {
067            copy(original, this);
068        }
069    
070        /**
071         * {@inheritDoc}
072         */
073        @Override
074        public synchronized void addValue(double v) {
075            super.addValue(v);
076        }
077    
078        /**
079         * {@inheritDoc}
080         */
081        @Override
082        public synchronized double apply(UnivariateStatistic stat) {
083            return super.apply(stat);
084        }
085    
086        /**
087         * {@inheritDoc}
088         */
089        @Override
090        public synchronized void clear() {
091            super.clear();
092        }
093    
094        /**
095         * {@inheritDoc}
096         */
097        @Override
098        public synchronized double getElement(int index) {
099            return super.getElement(index);
100        }
101    
102        /**
103         * {@inheritDoc}
104         */
105        @Override
106        public synchronized long getN() {
107            return super.getN();
108        }
109    
110        /**
111         * {@inheritDoc}
112         */
113        @Override
114        public synchronized double getStandardDeviation() {
115            return super.getStandardDeviation();
116        }
117    
118        /**
119         * {@inheritDoc}
120         */
121        @Override
122        public synchronized double[] getValues() {
123            return super.getValues();
124        }
125    
126        /**
127         * {@inheritDoc}
128         */
129        @Override
130        public synchronized int getWindowSize() {
131            return super.getWindowSize();
132        }
133    
134        /**
135         * {@inheritDoc}
136         */
137        @Override
138        public synchronized void setWindowSize(int windowSize) throws MathIllegalArgumentException {
139            super.setWindowSize(windowSize);
140        }
141    
142        /**
143         * {@inheritDoc}
144         */
145        @Override
146        public synchronized String toString() {
147            return super.toString();
148        }
149    
150        /**
151         * Returns a copy of this SynchronizedDescriptiveStatistics instance with the
152         * same internal state.
153         *
154         * @return a copy of this
155         */
156        @Override
157        public synchronized SynchronizedDescriptiveStatistics copy() {
158            SynchronizedDescriptiveStatistics result =
159                new SynchronizedDescriptiveStatistics();
160            // No try-catch or advertised exception because arguments are guaranteed non-null
161            copy(this, result);
162            return result;
163        }
164    
165        /**
166         * Copies source to dest.
167         * <p>Neither source nor dest can be null.</p>
168         * <p>Acquires synchronization lock on source, then dest before copying.</p>
169         *
170         * @param source SynchronizedDescriptiveStatistics to copy
171         * @param dest SynchronizedDescriptiveStatistics to copy to
172         * @throws NullArgumentException if either source or dest is null
173         */
174        public static void copy(SynchronizedDescriptiveStatistics source,
175                                SynchronizedDescriptiveStatistics dest)
176            throws NullArgumentException {
177            MathUtils.checkNotNull(source);
178            MathUtils.checkNotNull(dest);
179            synchronized (source) {
180                synchronized (dest) {
181                    DescriptiveStatistics.copy(source, dest);
182                }
183            }
184        }
185    }