HaniiPuppy

CombinedQueue get threadsafe attempt

Jul 5th, 2014
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.65 KB | None | 0 0
  1. public class CombinedQueue<T> implements Queue<T> // WIP
  2. {
  3.     final Collection<Queue<T>> memberQueues;
  4.     final Lambda<T, Comparable> keyGetter;
  5.    
  6.     public T get(boolean remove)
  7.     {
  8.         // This algorithm works. That's not to say it's ideal. It's contrived, and an obvious workaround for maintaining
  9.         // thread safety. If you happen to see this comment and know of a better algorithm for grabbing the next value
  10.         // from a memberqueue in order decided by keyGetter while maintaining thread-safety, tell me <3
  11.        
  12.         // Uses a lambda to derive a comparable rather than a comparator as using a comparator removes the ability to
  13.         // check whether the variable within the next value that's being measured is the same, which may happen where
  14.         // the compared value is changed in a way that still results in the value being next in the queue it's in.
  15.        
  16.         // Work on a copy of memberQueues
  17.         List<Queue<T>> memberQueuesCopy = getMemberQueuesCopyAsList();
  18.  
  19.         Queue<T> nextQueue = null;
  20.         T nextValue = null;
  21.         Comparable nextValueComparable = null;
  22.  
  23.         // Run through all member queues, filling those variables with the variables corresponding to the queue with the
  24.         // lowest next comparable derived via keyGetter.
  25.  
  26.         // Establish a queue has the next value by iterating through the rest of the list before returning to it, and if
  27.         // it still has the same values (that is, hasn't been modified in a way that affects its order in this queue)
  28.         // after having compared the old values against the rest of the collection, return it as the next value.
  29.  
  30.         // null values always come last.
  31.         for(int i = 0; i < 100; i++) // 100-loop threshhold
  32.         {
  33.             boolean populatedQueueFound = false;
  34.  
  35.             for(Queue<T> j : memberQueuesCopy)
  36.             {
  37.                 if(j != null)
  38.                 {
  39.                     synchronized(j)
  40.                     {
  41.                         if(!j.isEmpty())
  42.                         {
  43.                             populatedQueueFound = true;
  44.  
  45.                             T jValue = j.peek();
  46.  
  47.                             if(jValue == null && nextQueue == null) // If there is no next queue, use this one.
  48.                                 nextQueue = j;
  49.                             else if(jValue != null)
  50.                             {
  51.                                 Comparable jValueComparable = keyGetter.getMember(jValue);
  52.  
  53.                                 if(j == nextQueue)
  54.                                 {
  55.                                     if(nextValue == jValue &&
  56.                                        nextValueComparable == jValueComparable)
  57.                                     {
  58.                                         if(remove)
  59.                                             return nextQueue.remove();
  60.                                         else
  61.                                             return jValue;
  62.                                     }
  63.  
  64.                                     nextValue = jValue;
  65.                                     nextValueComparable = jValueComparable;
  66.                                 }
  67.                                 else
  68.                                 {
  69.                                     if((jValueComparable == null && nextQueue == null) || // There is no next queue, use this one.
  70.                                        (jValueComparable != null &&
  71.                                           (nextValueComparable == null || // Currently stored next value is null (last) and this one should be used before.
  72.                                            jValueComparable.compareTo(nextValueComparable) < 0))) // This one comes before the currently stored next value.
  73.                                     {
  74.                                         nextQueue = j;
  75.                                         nextValue = jValue;
  76.                                         nextValueComparable = jValueComparable;
  77.                                     }
  78.                                 }
  79.                             }
  80.                         }
  81.                     }
  82.                 }
  83.             }
  84.  
  85.             if(!populatedQueueFound)
  86.                 throw new NoSuchElementException();
  87.         }
  88.  
  89.         throw new RuntimeException("Loop threshhold reached for combined queue - either something is constantly " +
  90.                                    "modifying one of the reference queues, or there is a problem with the " +
  91.                                    "CombinedQueue.get method.");
  92.         // replace with specific exception pertaining to the threshhold reached.
  93.     }
  94. }
Advertisement
Add Comment
Please, Sign In to add comment