2017-03-08 3 views
-1

Ich versuche, mehrere Threads in scala und für einen einfachen Test, den ich führen Sie diesen Code auszuführen:Testamentsvollstrecker NewFixedThreadPool nicht geben, das erwartete Ergebnis

Executors.newFixedThreadPool(20).execute(new Runnable { 
     override def run(): Unit = {   
     println("Thread Started!") 
     } 
}) 

Soweit ich verstehen könnte, wäre es 20 Threads erstellen und rufen Sie die Druckfunktion, aber das ist nicht, was passiert. Es erstellt nur einen Thread, führt den Druck aus und hängt.

Kann mir jemand dieses Phänomen erklären?

+0

Ich würde davon ausgehen, dass dieser Code schnell genug auf einem einzigen Thread ausgeführt wird, damit der Thread-Pool keine zusätzlichen Threads zuweisen muss. –

+0

Sie erstellen 20 Threads, und nur einer von ihnen funktioniert. Es geht nicht um die Geschwindigkeit der Ausführung: Threads werden nichts tun, wenn Sie ihnen nichts zu tun geben. –

+0

Also, ich habe einen Kafka-Pool und ich möchte jedem Thread einen Consumer hinzufügen, der Code ist nicht schnell (es ist eine Weile), aber immer noch nur ein Thread. –

Antwort

2

Der Grund dafür ist, dass Sie die ExecutorService nicht herunterfahren. In Java (leider nicht vertraut mit Scala):

ExecutorService executor = Executors.newFixedThreadPool(20); // or 1. 
executor.execute(() -> System.out.println("...")); 
executor.shutdown(); 

, warum Sie die Nachricht nur einmal sehen: Sie 20 Threads erstellen, und geben nur eine von ihnen arbeiten. Threads werden nichts tun, wenn Sie ihnen nichts zu tun geben.

Ich glaube, Sie haben angenommen, dass dieser Code die ausführbaren auf jedem Thread im Pool ausführen würde. Das ist einfach nicht der Fall.

Wenn Sie dies 20 mal in verschiedenen Threads tun möchten, müssen Sie a) 20 Runnables einreichen; b) synchronisieren die Runnables damit sie tatsächlich auf separaten Threads ausgeführt werden müssen:

CountdownLatch latch = new CountdownLatch(1); 
ExecutorService executor = Executors.newFixedThreadPool(20); 
for (int i = 0; i < 20; ++i) { 
    executor.execute(() -> { 
    latch.await(); // exception handling omitted for clarity. 
    System.out.println("..."); 
    }); 
} 
latch.countdown(); 
executor.shutdown(); 

Der Riegel hier gewährleistet, dass die Fäden aufeinander warten, bevor fortgefahren wird. Ohne sie könnte die triviale Arbeit leicht auf einem Thread ausgeführt werden, bevor ein anderer Thread gesendet wird, sodass Sie nicht alle Threads im Pool verwenden würden.

Verwandte Themen