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 }