2012-12-04 20 views
16

Ho appena iniziato a esaminare la classe Executors di Java e il metodo newCachedThreadPool(). In base all'API, il pool di thread risultante riutilizza gli oggetti esistenti Thread per le nuove attività.In che modo un pool di thread memorizzato nella cache riutilizza i thread esistenti

Sono un po 'perplesso su come è stato implementato perché non sono riuscito a trovare alcun metodo nell'API Thread che consente di impostare il comportamento di un oggetto esistente Thread.

Ad esempio, è possibile creare una nuova Thread da un oggetto Runnable, il che rende la chiamata di Threadrun() metodo s' il Runnable. Tuttavia, non esiste un metodo setter nell'API Thread che utilizza un argomento come Runnable.

Apprezzerei qualsiasi suggerimento.

+0

La risposta IOW: un 'Thread' svolge quasi lo stesso compito (o dovrei dire sottoinsieme di compiti) come la combinazione di' Runnable' e 'ExecutorService' con l'eccezione che quest'ultima combo ti offre più funzionalità per avvantaggiarti di. Tanto che dovresti * davvero * considerare perché stai usando un 'Thread' solo se lo fai. – BAR

risposta

2

Gli esecutori fanno tutto per te in background. E sì, utilizza solo l'API del thread esistente.

Di seguito link è esempio di implementazione piscina Discussione implementato utilizzando classe Thread e Collezione API: http://www.ibm.com/developerworks/library/j-jtp0730/index.html

+0

Per qualche motivo il mio primo commento non è stato pubblicato. Grazie per il chiarimento. Quando ho postato la domanda ho assunto erroneamente che i thread non avessero alcuna conoscenza degli interni del pool di thread. –

4

ThreadPool ha le discussioni che cercano i lavori eseguibili. Invece di iniziare una nuova discussione da Runnable, la discussione chiamerà semplicemente la funzione run(). Quindi una discussione in un ThreadPool non viene creata con lo Runnable da te fornito, ma con una che controlla solo se alcune attività sono pronte per essere eseguite e le chiama direttamente.

Quindi sarebbe simile a questa:

while(needsToKeepRunning()){ 
    if(hasMoreTasks()){ 
     getFirstTask().run();. 
    } 
    else 
    { 
     waitForOtherTasks(); 
    } 
} 

Naturalmente questo è eccessivamente semplificato l'attuazione reale con l'attesa è molto più elegante. Una grande fonte di informazioni su come questo funziona davvero può essere trovato nel Concurrency in Practice

+0

Grazie. Fatto. (E grazie a tutti gli altri che hanno risposto alla mia domanda.) –

2

Bene il filo hanno solo chiamare Runnable.run() sui runnables che sono assegnati a lui ...

3

Le discussioni sono creati solo una volta in l'API del pool di thread (tranne nei casi in cui a causa di alcune eccezioni il thread esce bruscamente)

I thread Worker eseguono il polling della coda per verificare se è presente un'attività e utilizzarla. Quindi i fili non escono mai.

È solo un'astrazione che i thread vengono riutilizzati (l'astrazione perché non si fermano mai). Ovviamente si fermano dopo il timeout di inattività e la richiesta di spegnimento.

Runnable -----> Pool di thread (Alcuni thread di lavoro consuma che Runnable e altri aspettare ancora un po 'Runnables)

20

Immaginiamo Fondamentalmente ogni thread dal pool di fare questo:

public void run() { 
    while(true) { 
     if(tasks available) { 
      Runnable task = taskqueue.dequeue(); 
      task.run(); 
     } else { 
      // wait or whatever 
     } 
    } 
} 
2

Una spiegazione semplificata è che quando si passa un Runnable a ExecutorService il Runnable viene messo in coda. I thread worker ThreadPool leggono da questa coda e richiama il metodo runnables run() run().

+0

Grazie. Quando ho postato la domanda stavo assumendo che 'Thread's non fosse a conoscenza dell'implementazione del pool di thread. –

Problemi correlati