Por que o java ExecutorService newSingleThreadExecutor gera dois threads?

Eu tenho um código java de exemplo abaixo do qual, se executado como um aplicativo de console, se comporta como eu esperava (gerando um único thread para executar o executável).

O comportamento estranho (gerando dois threads - exemplo abaixo) é quando executo esse exemplo como um aplicativo de serviço usando o prunsrv64.exe do Apache.

Estou testando isso em uma máquina Windows 7 - 64 bits.

Saída de amostra:

   Thread -28 Current time: 09:50:11 AM
   Thread -52 Current time: 09:50:12 AM
   Thread -28 Current time: 09:50:21 AM
   Thread -52 Current time: 09:50:22 AM
   Thread -28 Current time: 09:50:31 AM
   Thread -52 Current time: 09:50:32 AM

Código de amostra:

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorTest{
    public void testIt(){
        ExecutorService ex = Executors.newSingleThreadExecutor();
        ex.execute(new Runnable(){
            public void run() {
                while(true){
                    System.out.printf("Thread -" + Thread.currentThread().getId() + " Current time: %tr%n", new Date());
                    try{
                        Thread.sleep(10000);    
                    }catch(InterruptedException ie){
                        ie.printStackTrace();
                    }                   
                }

            }
        });     
    }
}

Obrigado.

Atualização: Apenas para esclarecer, estou chamando esse código da seguinte maneira:

    ExecutorTest tester = new ExecutorTest();
    tester.testIt();

O mesmo código sem alterações está se comportando de maneira diferente quando executado como aplicativo de console e um aplicativo de serviço, como mencionado acima.

Atualização 2: eu adicionei um segundo testador que usa um ScheduledExecutorService. O comportamento é o mesmo.

Atualização Update2:

Using ScheduledExecutorService.
Thread Id outside Runnable -1
Thread -53 Current time: 10:58:15 AM
Thread -28 Current time: 10:58:24 AM
Thread -53 Current time: 10:58:25 AM
Thread -28 Current time: 10:58:34 AM
Thread -53 Current time: 10:58:35 AM
Thread -28 Current time: 10:58:44 AM
Thread -53 Current time: 10:58:45 AM
Thread -28 Current time: 10:58:54 AM
Thread -53 Current time: 10:58:55 AM
Thread -28 Current time: 10:59:04 AM
Thread -53 Current time: 10:59:05 AM

Código da atualização 2:

public void testItWithScheduled(){
    System.out.println("Using ScheduledExecutorService.");
    ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
    System.out.println("Thread Id outside Runnable -" + Thread.currentThread().getId());
    ex.scheduleWithFixedDelay(new Runnable(){
        public void run() {
            System.out.printf("Thread -" + Thread.currentThread().getId() + " Current time: %tr%n", new Date());
        }
    },0L, 10, TimeUnit.SECONDS);        
}


called through:

    ExecutorTest tester = new ExecutorTest();
    tester.testItWithScheduled();

Atualização 3: log modificado para adicionar hash de identidade

Using ScheduledExecutorService.
Thread Id outside Runnable 1 with reference: 1370756928
Thread -53 Current time: 11:10:38 AM with reference: 1370756928
Thread -28 Current time: 11:10:47 AM with reference: 1939972532
Thread -53 Current time: 11:10:48 AM with reference: 1370756928
Thread -28 Current time: 11:10:57 AM with reference: 1939972532
Thread -53 Current time: 11:10:58 AM with reference: 1370756928
Thread -28 Current time: 11:11:07 AM with reference: 1939972532
Thread -53 Current time: 11:11:08 AM with reference: 1370756928

questionAnswers(2)

yourAnswerToTheQuestion