1/*
2 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 4992438 6633113
27 * @summary Checks that fairness setting is respected.
28 */
29
30import java.util.concurrent.BlockingQueue;
31import java.util.concurrent.SynchronousQueue;
32import java.util.concurrent.locks.Condition;
33import java.util.concurrent.locks.ReentrantLock;
34
35public class Fairness {
36    private static void testFairness(boolean fair,
37                                     final BlockingQueue<Integer> q)
38        throws Throwable
39    {
40        final ReentrantLock lock = new ReentrantLock();
41        final Condition ready = lock.newCondition();
42        final int threadCount = 10;
43        final Throwable[] badness = new Throwable[1];
44        lock.lock();
45        for (int i = 0; i < threadCount; i++) {
46            final Integer I = i;
47            Thread t = new Thread() { public void run() {
48                try {
49                    lock.lock();
50                    ready.signal();
51                    lock.unlock();
52                    q.put(I);
53                } catch (Throwable t) { badness[0] = t; }}};
54            t.start();
55            ready.await();
56            // Probably unnecessary, but should be bullet-proof
57            while (t.getState() == Thread.State.RUNNABLE)
58                Thread.yield();
59        }
60        for (int i = 0; i < threadCount; i++) {
61            int j = q.take();
62            // Non-fair queues are lifo in our implementation
63            if (fair ? j != i : j != threadCount - 1 - i)
64                throw new Error(String.format("fair=%b i=%d j=%d%n",
65                                              fair, i, j));
66        }
67        if (badness[0] != null) throw new Error(badness[0]);
68    }
69
70    public static void main(String[] args) throws Throwable {
71        testFairness(false, new SynchronousQueue<Integer>());
72        testFairness(false, new SynchronousQueue<Integer>(false));
73        testFairness(true,  new SynchronousQueue<Integer>(true));
74    }
75}
76