I don't understand why seemingly just 4 new threads are started and counted, eventhough 8 are submitted.
Don't confuse between Threads and tasks.  You have created a fixed ThreadPool for 4 threads and only 4 threads will remain in the pool. 
Check implementation of Executors
 /**
     * Creates a thread pool that reuses a fixed number of threads
     * operating off a shared unbounded queue.  At any point, at most
     * <tt>nThreads</tt> threads will be active processing tasks.
     * If additional tasks are submitted when all threads are active,
     * they will wait in the queue until a thread is available.
     * If any thread terminates due to a failure during execution
     * prior to shutdown, a new one will take its place if needed to
     * execute subsequent tasks.  The threads in the pool will exist
     * until it is explicitly {@link ExecutorService#shutdown shutdown}.
     *
     * @param nThreads the number of threads in the pool
     * @return the newly created thread pool
     * @throws IllegalArgumentException if <tt>nThreads <= 0</tt>
     */
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
You can find more details about individual parameters of ThreadPoolExecutor at official documentation page. 
In your case, number of threads are 4. Number of worker tasks ( which are implementing Runnable interface) are 8.
How are they stored, how can they be accessed? Is it also possible to manipulate them midway, maybe why other calls arrive?
- Tasks are submitted to task queue ( 
BlockingQueue) 
- If 
BlockingQueue is full ( bounded queue), Rejection Policy will be triggered.  
- If BlockingQueue is not full, worker tasks will wait for Thread to pick-up them.
 
Related SE posts:
How to properly use Java Executor?
Task getting rejected although threads are available