Phaser Classe
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e CyclicBarrier
CountDownLatch
al supporto di un utilizzo più flessibile.
[Android.Runtime.Register("java/util/concurrent/Phaser", DoNotGenerateAcw=true)]
public class Phaser : Java.Lang.Object
[<Android.Runtime.Register("java/util/concurrent/Phaser", DoNotGenerateAcw=true)>]
type Phaser = class
inherit Object
- Ereditarietà
- Attributi
Commenti
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e CyclicBarrier
CountDownLatch
al supporto di un utilizzo più flessibile.
<b>Registrazione.</b> Diversamente dal caso di altre barriere, il numero di parti <registrate<>/em> per la sincronizzazione in un phaser può variare nel tempo. Le attività possono essere registrate in qualsiasi momento (usando metodi #register
, #bulkRegister
o forme di costruttori che stabiliscono numeri iniziali di parti) e facoltativamente annullate la registrazione in qualsiasi arrivo (utilizzando #arriveAndDeregister
). Come accade con la maggior parte dei costrutti di sincronizzazione di base, la registrazione e la registrazione influiscono solo sui conteggi interni; non stabiliscono ulteriori contabilità interne, quindi le attività non possono eseguire query se sono registrate. È tuttavia possibile introdurre tale contabilità sottoclassando questa classe.
<b>Sincronizzazione.</b> Come un CyclicBarrier
oggetto , può Phaser
essere atteso ripetutamente. Il metodo #arriveAndAwaitAdvance
ha un effetto analogo a java.util.concurrent.CyclicBarrier#await CyclicBarrier.await
. Ogni generazione di un phaser ha un numero di fase associato. Il numero di fase inizia a zero e avanza quando tutte le parti arrivano al phaser, avvolgendo intorno a zero dopo aver raggiunto Integer.MAX_VALUE
. L'uso dei numeri di fase consente il controllo indipendente delle azioni all'arrivo in un phaser e in attesa di altri, tramite due tipi di metodi che possono essere richiamati da qualsiasi parte registrata:
<ul>
<li><b>Arrivo.</b> Metodi #arrive
e #arriveAndDeregister
arrivo record. Questi metodi non bloccano, ma restituiscono un numero< di fase di arrivo/em> associato<>, ovvero il numero di fase del phaser a cui è applicato l'arrivo. Quando arriva la parte finale per una determinata fase, viene eseguita un'azione facoltativa e la fase avanza. Queste azioni vengono eseguite dall'entità che attiva un avanzamento di fase e vengono disposte eseguendo l'override del metodo #onAdvance(int, int)
, che controlla anche la terminazione. L'override di questo metodo è simile a , ma più flessibile rispetto a , fornendo un'azione barriera a un oggetto CyclicBarrier
.
<li><b>In attesa.<Il metodo #awaitAdvance
/b> richiede un argomento che indica un numero di fase di arrivo e restituisce quando il phaser avanza a (o è già in corrispondenza) di una fase diversa. A differenza di costruzioni simili che usano CyclicBarrier
, il metodo awaitAdvance
continua ad attendere anche se il thread in attesa viene interrotto. Sono disponibili anche versioni di interruptible e timeout, ma le eccezioni rilevate durante l'attesa delle attività in modo interrotto o con timeout non modificano lo stato del phaser. Se necessario, è possibile eseguire qualsiasi ripristino associato all'interno dei gestori di tali eccezioni, spesso dopo aver richiamato forceTermination
. I phaser possono essere usati anche dalle attività in esecuzione in un oggetto ForkJoinPool
. Lo stato di avanzamento viene garantito se il livello di parallelismo del pool può contenere il numero massimo di parti bloccate simultaneamente.
</ul>
<b>Terminazione.</b> Un phaser può entrare in uno <stato di terminazione< em>/em>, che può essere controllato usando il metodo #isTerminated
. Al termine, tutti i metodi di sincronizzazione restituiscono immediatamente senza attendere l'anticipo, come indicato da un valore restituito negativo. Analogamente, i tentativi di registrazione al termine non hanno alcun effetto. La terminazione viene attivata quando una chiamata di onAdvance
restituisce true
. L'implementazione predefinita restituisce true
se una registrazione ha causato il numero di parti registrate diventa zero. Come illustrato di seguito, quando le azioni di controllo phaser con un numero fisso di iterazioni, è spesso utile eseguire l'override di questo metodo per causare la terminazione quando il numero di fase corrente raggiunge una soglia. Il metodo #forceTermination
è disponibile anche per rilasciare improvvisamente thread in attesa e consentire loro di terminare.
<b>Suddivisione in livelli.</b> Phasers può essere <em>tiered/em> (ovvero costruito< in strutture ad albero) per ridurre i conflitti. I phaser con un numero elevato di parti che altrimenti riscontrano costi di contesa di sincronizzazione elevati possono essere configurati in modo che i gruppi di sub-phaser condividono un elemento padre comune. Ciò può aumentare notevolmente la velocità effettiva anche se comporta un sovraccarico maggiore per ogni operazione.
In un albero di phaser a livelli, la registrazione e la deregistrazione dei phaser figlio con il relativo padre vengono gestite automaticamente. Ogni volta che il numero di parti registrate di un phaser figlio diventa diverso da zero (come stabilito nel #Phaser(Phaser,int)
costruttore, #register
o #bulkRegister
), il phaser figlio viene registrato con il relativo padre. Ogni volta che il numero di parti registrate diventa zero come risultato di una chiamata di #arriveAndDeregister
, il phaser figlio viene annullata dalla registrazione dal padre.
<b>Monitoraggio.</b> Mentre i metodi di sincronizzazione possono essere richiamati solo da parti registrate, lo stato corrente di un phaser può essere monitorato da qualsiasi chiamante. In qualsiasi momento ci sono #getRegisteredParties
parti in totale, di cui #getArrivedParties
sono arrivate alla fase attuale (#getPhase
). Quando arrivano le parti rimanenti (#getUnarrivedParties
), la fase avanza. I valori restituiti da questi metodi possono riflettere gli stati temporanei e pertanto non sono in generale utili per il controllo della sincronizzazione. Il metodo #toString
restituisce snapshot di queste query di stato in un formato pratico per il monitoraggio informale.
Effetti di coerenza della memoria: le azioni prima di qualsiasi forma di metodo <di arrivo si>verificano prima</i> di un avanzamento di fase corrispondente e le azioni onAdvance (se presenti), che a loro volta si verificano prima delle azioni che seguono l'avanzamento della fase.
<b>Esempi di utilizzo:</b>
Un Phaser
oggetto può essere utilizzato invece di un CountDownLatch
oggetto per controllare un'azione singola che gestisce un numero variabile di parti. Il linguaggio tipico è per il metodo che imposta questo fino al primo registro, quindi avviare tutte le azioni, quindi annullare la registrazione, come in:
{@code
void runTasks(List<Runnable> tasks) {
Phaser startingGate = new Phaser(1); // "1" to register self
// create and start threads
for (Runnable task : tasks) {
startingGate.register();
new Thread(() -> {
startingGate.arriveAndAwaitAdvance();
task.run();
}).start();
}
// deregister self to allow threads to proceed
startingGate.arriveAndDeregister();
}}
Un modo per fare in modo che un set di thread esegua ripetutamente azioni per un determinato numero di iterazioni consiste nell'eseguire l'override onAdvance
di :
{@code
void startTasks(List<Runnable> tasks, int iterations) {
Phaser phaser = new Phaser() {
protected boolean onAdvance(int phase, int registeredParties) {
return phase >= iterations - 1 || registeredParties == 0;
}
};
phaser.register();
for (Runnable task : tasks) {
phaser.register();
new Thread(() -> {
do {
task.run();
phaser.arriveAndAwaitAdvance();
} while (!phaser.isTerminated());
}).start();
}
// allow threads to proceed; don't wait for them
phaser.arriveAndDeregister();
}}
Se l'attività principale deve attendere in un secondo momento la terminazione, può eseguire nuovamente la registrazione e quindi eseguire un ciclo simile:
{@code
// ...
phaser.register();
while (!phaser.isTerminated())
phaser.arriveAndAwaitAdvance();}
Le costruzioni correlate possono essere usate per attendere numeri di fase specifici nei contesti in cui si è certi che la fase non verrà mai a capo intorno Integer.MAX_VALUE
a . Ad esempio:
{@code
void awaitPhase(Phaser phaser, int phase) {
int p = phaser.register(); // assumes caller not already registered
while (p < phase) {
if (phaser.isTerminated())
// ... deal with unexpected termination
else
p = phaser.arriveAndAwaitAdvance();
}
phaser.arriveAndDeregister();
}}
Per creare un set di n
attività usando un albero di phaser, è possibile usare il codice del formato seguente, presupponendo che una classe Task con un costruttore che accetti un Phaser
oggetto con cui viene registrato al momento della costruzione. Dopo la chiamata di build(new Task[n], 0, n, new Phaser())
, è possibile avviare queste attività, ad esempio inviando a un pool:
{@code
void build(Task[] tasks, int lo, int hi, Phaser ph) {
if (hi - lo > TASKS_PER_PHASER) {
for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
int j = Math.min(i + TASKS_PER_PHASER, hi);
build(tasks, i, j, new Phaser(ph));
}
} else {
for (int i = lo; i < hi; ++i)
tasks[i] = new Task(ph);
// assumes new Task(ph) performs ph.register()
}
}}
Il valore migliore di TASKS_PER_PHASER
dipende principalmente dalle frequenze di sincronizzazione previste. Un valore minimo di quattro può essere appropriato per corpi di attività estremamente piccoli per fase (quindi tassi elevati) o fino a centinaia per quelli estremamente grandi.
<b>Note sull'implementazione:</b> Questa implementazione limita il numero massimo di parti a 65535. I tentativi di registrazione di altre parti comportano IllegalStateException
. Tuttavia, è possibile e creare phaser a livelli per ospitare set arbitrariamente elevati di partecipanti.
Aggiunta nella versione 1.7.
Documentazione java per java.util.concurrent.Phaser
.
Le parti di questa pagina sono modifiche basate sul lavoro creato e condiviso dal progetto Open Source Android e usato in base ai termini descritti nella licenza Creative Commons 2.5 Attribuzione.
Costruttori
Phaser() |
Crea un nuovo phaser senza parti inizialmente registrate, nessun elemento padre e numero di fase iniziale 0. |
Phaser(Int32) |
Crea un nuovo phaser con il numero specificato di parti registrate senza problemi, nessun elemento padre e numero di fase iniziale 0. |
Phaser(IntPtr, JniHandleOwnership) |
Costruttore usato durante la creazione di rappresentazioni gestite di oggetti JNI; chiamato dal runtime. |
Phaser(Phaser) |
È equivalente a |
Phaser(Phaser, Int32) |
Crea un nuovo phaser con l'elemento padre specificato e il numero di parti registrate senza problemi. |
Proprietà
ArrivedParties |
Restituisce il numero di parti registrate che sono arrivate alla fase corrente di questo phaser. |
Class |
Restituisce la classe di runtime di questo |
Handle |
Handle per l'istanza di Android sottostante. (Ereditato da Object) |
IsTerminated |
Restituisce |
JniIdentityHashCode |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
JniPeerMembers |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
Parent |
Restituisce l'elemento padre di questo phaser o |
PeerReference |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
Phase |
Restituisce il numero di fase corrente. |
RegisteredParties |
Restituisce il numero di parti registrate in questa fase. |
Root |
Restituisce il predecessore radice di questo phaser, che corrisponde a questo phaser se non ha un elemento padre. |
ThresholdClass |
Questa API supporta l'infrastruttura Mono per Android e non deve essere usata direttamente dal codice. |
ThresholdType |
Questa API supporta l'infrastruttura Mono per Android e non deve essere usata direttamente dal codice. |
UnarrivedParties |
Restituisce il numero di parti registrate che non sono ancora arrivate alla fase corrente di questo phaser. |
Metodi
Arrive() |
Arriva a questa fase, senza aspettare che altri arrivino. |
ArriveAndAwaitAdvance() |
Arriva a questo phaser e attende gli altri. |
ArriveAndDeregister() |
Arriva a questo phaser e deregista da esso senza aspettare che gli altri arrivino. |
AwaitAdvance(Int32) |
Attende la fase di questo phaser per avanzare dal valore di fase specificato, restituendo immediatamente se la fase corrente non è uguale al valore della fase specificata o questo phaser viene terminato. |
AwaitAdvanceInterruptibly(Int32) |
Attende la fase di questo phaser per passare dal valore di fase specificato, generando |
AwaitAdvanceInterruptibly(Int32, Int64, TimeUnit) |
Attende la fase di questo phaser per passare dal valore di fase specificato o dal timeout specificato alla scadenza, generando |
BulkRegister(Int32) |
Aggiunge il numero specificato di nuove parti non risolte a questa fase. |
Clone() |
Crea e restituisce una copia di questo oggetto. (Ereditato da Object) |
Dispose() |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
Dispose(Boolean) |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
Equals(Object) |
Indica se un altro oggetto è "uguale a" questo. (Ereditato da Object) |
ForceTermination() |
Forza questo phaser a immettere lo stato di terminazione. |
GetHashCode() |
Restituisce un valore del codice hash per l'oggetto. (Ereditato da Object) |
JavaFinalize() |
Chiamato dal Garbage Collector su un oggetto quando Garbage Collection determina che non sono presenti altri riferimenti all'oggetto . (Ereditato da Object) |
Notify() |
Riattiva un singolo thread in attesa del monitor dell'oggetto. (Ereditato da Object) |
NotifyAll() |
Riattiva tutti i thread in attesa del monitor dell'oggetto. (Ereditato da Object) |
OnAdvance(Int32, Int32) |
Metodo sostituibile per eseguire un'azione in caso di avanzamento della fase in sospeso e per controllare la terminazione. |
Register() |
Aggiunge una nuova parte non risolta a questo phaser. |
SetHandle(IntPtr, JniHandleOwnership) |
Imposta la proprietà Handle. (Ereditato da Object) |
ToArray<T>() |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
ToString() |
Restituisce una rappresentazione di stringa dell'oggetto. (Ereditato da Object) |
UnregisterFromRuntime() |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
Wait() |
Fa sì che il thread corrente attenda finché non viene risvegliato, in genere ricevendo <>una notifica</em> o <em>interrotto</em>. (Ereditato da Object) |
Wait(Int64) |
Fa sì che il thread corrente attenda finché non viene risvegliato, in genere ricevendo>< una notifica</em> o <em>interrotto</em> o fino a quando non è trascorsa una determinata quantità di tempo reale. (Ereditato da Object) |
Wait(Int64, Int32) |
Fa sì che il thread corrente attenda finché non viene risvegliato, in genere ricevendo>< una notifica</em> o <em>interrotto</em> o fino a quando non è trascorsa una determinata quantità di tempo reale. (Ereditato da Object) |
Implementazioni dell'interfaccia esplicita
IJavaPeerable.Disposed() |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
IJavaPeerable.DisposeUnlessReferenced() |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
IJavaPeerable.Finalized() |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
IJavaPeerable.JniManagedPeerState |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
IJavaPeerable.SetPeerReference(JniObjectReference) |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
Metodi di estensione
JavaCast<TResult>(IJavaObject) |
Esegue una conversione del tipo di tipo controllato dal runtime Android. |
JavaCast<TResult>(IJavaObject) |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |
GetJniTypeName(IJavaPeerable) |
Una barriera di sincronizzazione riutilizzabile, simile alla funzionalità e |