1 package org.apache.maven.surefire.util.internal;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 /**
23 * A producer/consumer queue that is optimized for *one* producer thread
24 * and *one* consumer thread, and solely optimized for efficient inserts
25 * by the producer, minimizing producer locking for hand-off to
26 * a second consumer.
27 *
28 * TwoThreadBlockingQueue insert 5000000 elements in = 52
29 * FunkyTwoThreadBlockingQueue insert 5000000 elements in = 42
30 * TwoThreadBlockingQueue produced and taken 5000000 elements in = 104
31 * LinkedBlockingQueue insert 5000000 elements in = 1815
32 * LinkedBlockingDeque insert 5000000 elements in = 113
33 * ArrayList insert 5000000 elements in = 18
34 * LinkedList insert 5000000 elements in = 334
35 *
36 * @author Kristian Rosenvold
37 */
38 public class FunkyTwoThreadBlockingQueue implements BlockingQueue
39 {
40 final int chunkSize = 100;
41
42 private Chunk takeChunk = new Chunk();
43
44 private int takePos = 0;
45
46 private Chunk insertChunk = takeChunk;
47
48 private int insertPos = 0;
49
50 private volatile boolean memoryModelGuard;
51
52
53 public void put( Object object )
54 {
55 insertChunk.elements[insertPos] = object;
56 if ( ++insertPos == chunkSize)
57 {
58 Chunk newChunk = new Chunk();
59 insertChunk.next = newChunk;
60 insertChunk = newChunk;
61 insertPos = 0;
62 }
63 memoryModelGuard = true;
64 }
65
66 public void add( Object object )
67 {
68 put( object );
69 }
70
71
72 public Object take()
73 throws InterruptedException
74 {
75 if ( takePos >= chunkSize )
76 {
77 takeChunk = takeChunk.next;
78 takePos = 0;
79 }
80
81 boolean fud = memoryModelGuard;
82 Object next = takeChunk.elements[takePos];
83 while ( next == null )
84 {
85 Thread.sleep( 1 );
86 fud = memoryModelGuard;
87 next = takeChunk.elements[takePos];
88 }
89 takePos++;
90 return next;
91 }
92
93 final class Chunk
94 {
95 final Object[] elements = new Object[chunkSize];
96
97 volatile Chunk next;
98 }
99 }