Dividing a ThreadPool class into component classes to reduce/isolate complexity I have a ThreadPool class which has grown to a point where it is becoming difficult to keep all of this unit of work in mind. It is also becoming harder to read. For this reason I would like to break this class into component classes.

First of all here is the class header with comments:

//ThreadPool.h

#ifndef THREADPOOL_H
#define THREADPOOL_H

#define doNothing()

#include &lt;iostream&gt;
#include &lt;chrono&gt;
#include &lt;queue&gt;
#include &lt;vector&gt;
#include &lt;functional&gt;
#include &lt;thread&gt;
#include &lt;mutex&gt;
#include &lt;condition_variable&gt;

typedef std::function&lt; void() &gt; voidFunctionType;  

class ThreadPool{

 public:
  ThreadPool(unsigned int desiredThreadCount);
  ~ThreadPool();

  //Functions Affecting ThreadPool
  //Function used by threads to submit work to ThreadPool
  void workSubmit(voidFunctionType functionPointer);
  //Function used by threads to take work from ThreadPool
  voidFunctionType takeTask(void);
  //Function which returns the number of work in the queue
  unsigned int workCount(void);
  //Function which 
  bool isWorkAvailable(void);

  //Functions Affecting Thread Availability.
  //Increments availableThreads variable which indicates number of threads available
  void incThreadAvailability(void);
  //Decrements availableThreads variable which indicates number of treads available
  void decThreadAvailability(void);
  //Returns availableThreads variable which indicates number of threads available
  unsigned int getThreadAvailability(void);
  //Function returns total number of threads generated
  unsigned int getThreadNum(void);

  //Functions Affecting Threads
  //Checks to see if work is available, if work is not available thread is put to sleep
  //If work is available thread processes work. 
  void threadSleepUntillWorkAvail(void);

 private:
  // Number of threads generated
  unsigned int numberOfThreads;

  //Vector of threads
  std::vector&lt;std::thread&gt; workers;

  // Number of threads available to process work
  unsigned int availableThreads;
  // Mutex for the availableThreads variable
  std::mutex threadAvailabilityLock;
  std::unique_lock&lt;std::mutex&gt; threadAvailabilityLockUnique;

  //Workqueue to track work
  std::queue&lt; std::function&lt; void()&gt; &gt; workQueue;
  //WorkSubmissionLock mutex is used to lock submission of work only
  std::mutex workSubmissionLock;
  std::unique_lock&lt;std::mutex&gt; workSubmissionLockUnique;
  std::condition_variable workSubmissionCondition;
  //WorkQueueLock mutex is used to lock all access points to the queue it self
  std::mutex workQueueLock;
  std::unique_lock&lt;std::mutex&gt; workQueueLockUnique;
  std::condition_variable workQueueCondition;

  //Private Member Functions
  //workAccept is used within workSubmit. This function is used to load the workQueue with the
  //Accepted work. 
  void workAccept(voidFunctionType functionPointer);

  //Operators
  //Function executed by threads.
  void operator()(void); 
};
#endif


I have tried creating a thread component class, however it was highly coupled with the ThreadPool class and the only value it provided was a single routine which was the main routine the threads executed. So I replaced this class with the function method operator within the threadpool class. 

Other than the thread class component I am unsure if I can extract out any other single responsibility from this class.

Note: 


I am aware of a resource deadlock problem when 3 or more threads are created, I do not want this issue to be the focal point.
I do not think the implementation is relevant to the question, however, it can be viewed here.
There are way too many member variables:

unsigned int numberOfThreads;
std::vector&lt;std::thread&gt; workers;
unsigned int availableThreads;


Can you not find the number of threads with workers.size(). What's the difference between number of Threads and Available Threads and more importantly why do you need to know!

You have three mutex's and two condition variables! Why? Also why are you putting the unique_lock as a member of the class! That would make them hard to use in a shared context.

Normally I would expect to see:

//In class:
    std::mutex               lock;
    std::condition_variable  sync;

//Adding Stuff Function:
    std::lock_guard   guard(lock);
    queue.push(item);
    sync.notify();

//Taking stuff from Queue
    std::lock_guard   guard(lock);
    sync.wait(guard, [queue](){!queue.empty();});
    if (!queue.empty()) {
        result = queue.pop();
    }


The only method that should be public on that class is adding a new job. All other methods are private members.

This is what mine would look like this:

class WorkQueue
{
    private:
        std::vector&lt;std::thread&gt;            threads;
        std::deque&lt;std::function&lt;void()&gt;&gt;   queue;
        std::mutex                          lock;
        std::condition_variable             sync;
        bool                                finished;

        std::function&lt;void()&gt; getWork();
        void work();
    public:
        WorkQueue(int threadCount);
        ~WorkQueue();
        template&lt;typename F&gt;
        void addWork(F&amp;&amp; func);
};