 
 import Foundation
 
+///
+/// Key used to retrieve the binding context on the current queue
+///
 private let _contextSpecificName = DispatchSpecificKey<QueueBindingContext>();
 
 ///
-/// Binding context queue to use if the current queue is not already a binding queue
-///
-/// This is not used for the purposes of serialization but rather because creating new queues is bad for performance.
-/// This can have the unexpected consequence that all computed values are computed on the same queue.
-///
-private let _defaultContextQueue = BindingContext.createQueueWithNewContext();
+/// Semaphore used to decide which context queue to use
+///
+private let _queueSemaphore = DispatchSemaphore(value: 1);
+
+///
+/// Semaphore that is held as long as there are 0 queues available
+///
+private let _queueWaitSemaphore = DispatchSemaphore(value: 1);
+
+///
+/// Queues used to
+///
+private var _contextQueues = BindingQueuePool.createContextQueues(8);
 
 ///
 /// Stores the binding context for the current queue

        queue.setSpecific(key: _contextSpecificName, value: storage);
        
        return queue;
    }
    
    ///

            action();
            existingStorage.context = oldContext;
        } else {
            // Current queue doesn't have any context stored, move on to a queue
            // Could also call createQueueWithNewContext() here, but that is slow
            let queue = BindingQueuePool.retrieveContextQueue();
            defer { BindingQueuePool.returnContextQueue(queue); }
            
            queue.sync(execute: {
                let existingStorage = BindingContext.currentStorage!;
                
                // Generate a new context
