У меня есть пример java-кода, ниже которого, если он запускается как консольное приложение, ведет себя так, как я ожидал (создавая один поток для выполнения runnable).Почему java ExecutorService newSingleThreadExecutor порождает два потока?
Странное поведение (порождение двух потоков - пример ниже) Я вижу, когда я запускаю этот образец в качестве приложения-приложения с помощью apun's prunsrv64.exe.
Я тестирую это на машине с Windows 7 - 64 бит.
Пример вывода:
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
Пример кода:
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();
}
}
}
});
}
}
Спасибо.
Update: Просто для уточнения я называю этот код следующим образом:
ExecutorTest tester = new ExecutorTest();
tester.testIt();
тот же код без изменений ведет себя по-разному при ее запуске консольного приложения и приложения-службы, как я уже упоминал выше.
Обновление 2: Я добавил второй тестер, который использует ScheduledExecutorService. Поведение такое же.
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
Update 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();
Update 3: Модифицированный каротаж добавить идентичности окрошка
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
Возможно, вы просто вызываете 'testIt' дважды? –
Я бы предположил, что у вас есть ваш основной поток, запускающий программу, а затем вы создаете 'Executors.newSingleThreadExecutor();' который создает другой поток. Результат состоит из двух потоков. –
У вас есть 2 разных идентификатора потоков, если вы поместите println getId() прямо перед циклом while? – brummfondel