Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
TwoThreadBlockingQueue |
|
| 2.3333333333333335;2.333 | ||||
TwoThreadBlockingQueue$Element |
|
| 2.3333333333333335;2.333 |
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 | * The producer can actually come in on different threads | |
29 | * (because lastInserted is volatile), but can/will lose | |
30 | * items if they arrive concurrently. Take only supports a single | |
31 | * client. | |
32 | * | |
33 | * This runs like crazy, but is not the most garbage friendly around. | |
34 | * | |
35 | * TwoThreadBlockingQueue insert 5000000 elements in = 52ms | |
36 | * LinkedBlockingQueue insert 5000000 elements in = 179ms | |
37 | * LikedBlockingDeque insert 5000000 elements in = 114ms | |
38 | * ArrayList insert 5000000 elements in = 18ms (sized at correct size from start) | |
39 | * | |
40 | * @author Kristian Rosenvold | |
41 | */ | |
42 | 0 | public class TwoThreadBlockingQueue |
43 | implements BlockingQueue | |
44 | { | |
45 | private volatile Element lastInserted; | |
46 | private volatile Element lastTaken; | |
47 | private volatile Element first; | |
48 | ||
49 | 0 | public static final Object poison = new Object(); |
50 | ||
51 | public void add( Object object ) | |
52 | { | |
53 | 0 | Element next = new Element( object); |
54 | 0 | if (lastInserted == null){ |
55 | 0 | first = lastInserted = next; |
56 | } else { | |
57 | 0 | lastInserted.next = next; |
58 | 0 | lastInserted = next; |
59 | } | |
60 | 0 | } |
61 | ||
62 | public Object take() | |
63 | throws InterruptedException | |
64 | { | |
65 | 0 | if (lastTaken == null){ |
66 | 0 | while (first == null){ |
67 | 0 | Thread.sleep(1); |
68 | } | |
69 | 0 | lastTaken = first; |
70 | 0 | first = null; |
71 | } else { | |
72 | 0 | Element next = lastTaken.next; |
73 | 0 | while (next == null){ |
74 | 0 | Thread.sleep(1); |
75 | 0 | next = lastTaken.next; |
76 | } | |
77 | 0 | lastTaken = next; |
78 | } | |
79 | 0 | return lastTaken.object; |
80 | } | |
81 | ||
82 | 0 | private static class Element |
83 | { | |
84 | private final Object object; | |
85 | ||
86 | private volatile Element next; | |
87 | ||
88 | Element( Object object ) | |
89 | 0 | { |
90 | 0 | this.object = object; |
91 | 0 | } |
92 | } | |
93 | ||
94 | } |