2015-10-15 7 views
6

In un ForkJoinPoolForkJoinTask, il thread di lavoro corrente partecipa al furto del lavoro?L'attuale lavoratore partecipa al furto del lavoro?

Ho letto le implicazioni che un pool di fork join può lavorare rubare da thread bloccati o in attesa. L'attuale lavoratore sembra un candidato ovvio. Una volta che il lavoratore chiama .join() su un'altra attività, tale attività viene essenzialmente bloccata.

D'altra parte, vedo molti articoli che implicano conclusioni diverse. Ad esempio, il consenso generale sul fatto che il thread di lavoro corrente dovrebbe funzionare prima di attendere le attività biforcute.

Ci sono alcuni articoli che trattano l'uso di ForkJoinTask.getSurplusQueuedTaskCount come metodo di bilanciamento del lavoro nella coda avendo il lavoratore corrente fanno parte del lavoro. Se anche il lavoratore attuale sta rubando, questo non sembra necessario.

Naturalmente, vorrei massimizzare le operazioni di thread e mantenere tutti i lavoratori al massimo. Capire se il thread corrente ruba anche il lavoro (ad esempio quando viene chiamato .join) aiuterà a chiarire.

+0

È necessario uno specifico tipo di problema per essere al massimo vedere http://stackoverflow.com/questions/7926864/ how-is-the-fork-join-framework-better-a-thread-pool –

+1

Ho scritto uno di questi articoli e posso garantirvi che join() non risulta in work-stealing http: // coopsoft .com/it/Calamity2Article.html # join Il furto di lavoro è valido solo quando il deque è vuoto. Personalmente, non avrei microgestito il framework con getSurplus .... ecc. – edharned

risposta

2

È responsabilità di ForkJoinPool gestire i thread. Il codice client deve alimentare i task, non il microgestione del threading. Nota che le attività e i thread sono due cose diverse; le attività sono unità di lavoro da eseguire e i thread eseguono quel lavoro.

ForkJoinTask.compute() dovrebbe fork() in sottotasks più piccoli se l'attività è sufficientemente ampia da trarre vantaggio dall'esecuzione di parti dell'attività in parallelo e semplicemente elaborare l'attività se l'attività è sufficientemente piccola da essere eseguita correttamente in un singolo thread. Se il lavoro risulta essere più del previsto, può fork() parte del lavoro e fa il resto.

Se ForkJoinTask.compute() si sposta in sottoattività secondarie, può chiamare join() prima di tornare. ForkJoinPool quindi libererà il thread per lavorare su altre attività o genererà una discussione temporanea per lavorare su altre attività per garantire che il parallelismo disponibile sia completamente utilizzato.

Penso che sia ragionevole supporre che il numero appropriato di thread di lavoro sia tenuto occupato fino a quando ci sono attività non completate, a meno che non si blocchi esplicitamente il thread nel metodo compute().

Il Sole esercitazione fornisce informazioni più specifiche su come utilizzare queste classi:

https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html