Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
FunkyTwoThreadBlockingQueue |
|
| 2.0;2 | ||||
FunkyTwoThreadBlockingQueue$Chunk |
|
| 2.0;2 |
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 | 0 | public class FunkyTwoThreadBlockingQueue implements BlockingQueue |
39 | { | |
40 | 0 | final int chunkSize = 100; |
41 | ||
42 | 0 | private Chunk takeChunk = new Chunk(); |
43 | ||
44 | 0 | private int takePos = 0; |
45 | ||
46 | 0 | private Chunk insertChunk = takeChunk; |
47 | ||
48 | 0 | private int insertPos = 0; |
49 | ||
50 | private volatile boolean memoryModelGuard; | |
51 | ||
52 | ||
53 | public void put( Object object ) | |
54 | { | |
55 | 0 | insertChunk.elements[insertPos] = object; |
56 | 0 | if ( ++insertPos == chunkSize) |
57 | { | |
58 | 0 | Chunk newChunk = new Chunk(); |
59 | 0 | insertChunk.next = newChunk; |
60 | 0 | insertChunk = newChunk; |
61 | 0 | insertPos = 0; |
62 | } | |
63 | 0 | memoryModelGuard = true; |
64 | 0 | } |
65 | ||
66 | public void add( Object object ) | |
67 | { | |
68 | 0 | put( object ); |
69 | 0 | } |
70 | ||
71 | ||
72 | public Object take() | |
73 | throws InterruptedException | |
74 | { | |
75 | 0 | if ( takePos >= chunkSize ) |
76 | { | |
77 | 0 | takeChunk = takeChunk.next; |
78 | 0 | takePos = 0; |
79 | } | |
80 | ||
81 | 0 | boolean fud = memoryModelGuard; |
82 | 0 | Object next = takeChunk.elements[takePos]; |
83 | 0 | while ( next == null ) |
84 | { | |
85 | 0 | Thread.sleep( 1 ); |
86 | 0 | fud = memoryModelGuard; |
87 | 0 | next = takeChunk.elements[takePos]; |
88 | } | |
89 | 0 | takePos++; |
90 | 0 | return next; |
91 | } | |
92 | ||
93 | 0 | final class Chunk |
94 | { | |
95 | 0 | final Object[] elements = new Object[chunkSize]; |
96 | ||
97 | volatile Chunk next; | |
98 | } | |
99 | } |