def run
      @done = false
      @manager_running = false
      reaper = nil

      while @queue.size > 0
        if @threads.size <= @max_threads
          @threads << Thread.new(@queue.pop) do |proc|
            Thread.current[:thread_state] = "running"
            @klass.new.instance_exec(proc[:params], &proc[:block])
            Thread.current[:thread_state] = "done"
          end       
        else
          unless @manager_running
            reaper = manage_threads 
            @manager_running = true
          end
          sleep 1
        end
      end   
      
      # Run manager if thread size never reached max
      reaper = manage_threads unless @manager_running

      # Waits until all threads are completed
      # Before exiting
      reaper.join
    end
def run
      @done = false
      @manager_running = false
      reaper = nil

      while @queue.size > 0
        if @threads.size <= @max_threads
          @threads << Thread.new(@queue.pop) do |proc|
            Thread.current[:thread_state] = "running"
            @klass.new.instance_exec(proc[:params], &proc[:block])
            Thread.current[:thread_state] = "done"
          end       
        else
          unless @manager_running
            reaper = manage_threads 
            @manager_running = true
          end
          sleep 1
        end
      end   
      
      # Run manager if thread size never reached max
      reaper = manage_threads unless @manager_running

      # Waits until all threads are completed
      # Before exiting
      reaper.join
    end
Runs while there are jobs in the queue
 Waits for a second and checks for available threads
 Exits when all jobs are allocated in threads