View Javadoc

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  public class TwoThreadBlockingQueue
43      implements BlockingQueue
44  {
45      private volatile Element lastInserted;
46      private volatile Element lastTaken;
47      private volatile Element first;
48  
49      public static final Object poison = new Object();
50  
51      public void add( Object object )
52      {
53          Element next = new Element( object);
54          if (lastInserted == null){
55              first = lastInserted = next;
56          } else {
57              lastInserted.next = next;
58              lastInserted = next;
59          }
60      }
61  
62      public Object take()
63          throws InterruptedException
64      {
65          if (lastTaken == null){
66              while (first == null){
67                  Thread.sleep(1);
68              }
69              lastTaken = first;
70              first = null;
71          } else {
72              Element next = lastTaken.next;
73              while (next == null){
74                  Thread.sleep(1);
75                  next = lastTaken.next;
76              }
77              lastTaken = next;
78          }
79          return lastTaken.object;
80      }
81  
82      private static class Element
83      {
84          private final Object object;
85  
86          private volatile Element next;
87  
88          Element( Object object )
89          {
90              this.object = object;
91          }
92      }
93  
94  }