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 }