CountedCompleter Classe
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
A ForkJoinTask
com uma ação de conclusão executada quando acionada e não há ações pendentes restantes.
[Android.Runtime.Register("java/util/concurrent/CountedCompleter", ApiSince=24, DoNotGenerateAcw=true)]
[Java.Interop.JavaTypeParameters(new System.String[] { "T" })]
public abstract class CountedCompleter : Java.Util.Concurrent.ForkJoinTask
[<Android.Runtime.Register("java/util/concurrent/CountedCompleter", ApiSince=24, DoNotGenerateAcw=true)>]
[<Java.Interop.JavaTypeParameters(new System.String[] { "T" })>]
type CountedCompleter = class
inherit ForkJoinTask
- Herança
- Atributos
Comentários
A ForkJoinTask
com uma ação de conclusão executada quando acionada e não há ações pendentes restantes. CountedCompleters são, em geral, mais robustos na presença de bloqueios e bloqueios de subtarefas do que outras formas de ForkJoinTasks, mas são menos intuitivos para programar. Os usos de CountedCompleter são semelhantes aos de outros componentes baseados em conclusão (como java.nio.channels.CompletionHandler
), exceto que várias <conclusões pendentes></em> podem ser necessárias para acionar a ação #onCompletion(CountedCompleter)
de conclusão, e não apenas uma. A menos que inicializado de outra forma, a contagem pendente #getPendingCount começa em zero, mas pode ser (atomicamente) alterada usando os métodos #setPendingCount
, #addToPendingCount
e #compareAndSetPendingCount
. Após a invocação de , se a contagem de ações pendentes for diferente de zero, ela será diminuída, caso contrário, a ação de #tryComplete
conclusão será executada e, se esse próprio completo tiver um completo, o processo será continuado com seu completor. Como é o caso de componentes de sincronização relacionados, como Phaser
e Semaphore
, esses métodos afetam apenas contagens internas, eles não estabelecem nenhuma outra escrituração interna. Em particular, as identidades das tarefas pendentes não são mantidas. Conforme ilustrado abaixo, você pode criar subclasses que registram algumas ou todas as tarefas pendentes ou seus resultados quando necessário. Como ilustrado abaixo, métodos de utilidade que suportam a personalização de travessias de conclusão também são fornecidos. No entanto, como CountedCompleters fornece apenas mecanismos básicos de sincronização, pode ser útil criar outras subclasses abstratas que mantêm vínculos, campos e métodos de suporte adicionais apropriados para um conjunto de usos relacionados.
Uma classe CountedCompleter concreta deve definir o método #compute
, que deve, na maioria dos casos (conforme ilustrado abaixo), invocar tryComplete()
uma vez antes de retornar. A classe também pode opcionalmente substituir o método #onCompletion(CountedCompleter)
para executar uma ação após a conclusão normal e o método #onExceptionalCompletion(Throwable, CountedCompleter)
para executar uma ação em qualquer exceção.
CountedCompleters na maioria das vezes não apresentam resultados, caso em que são normalmente declarados como CountedCompleter<Void>
, e sempre retornarão null
como um valor de resultado. Em outros casos, você deve substituir o método #getRawResult
para fornecer um resultado de join(), invoke()
e métodos relacionados. Em geral, esse método deve retornar o valor de um campo (ou uma função de um ou mais campos) do objeto CountedCompleter que contém o resultado após a conclusão. Método #setRawResult
por padrão não desempenha nenhuma função em CountedCompleters. É possível, mas raramente aplicável, substituir esse método para manter outros objetos ou campos que contêm dados de resultado.
Um CountedCompleter que não tem um completer (ou seja, um para o qual #getCompleter
retorna null
) pode ser usado como um ForkJoinTask regular com essa funcionalidade adicionada. No entanto, qualquer completer que, por sua vez, tenha outro completer serve apenas como um auxiliar interno para outros cálculos, de modo que seu próprio status de tarefa (conforme relatado em métodos como ForkJoinTask#isDone
) é arbitrário, esse status muda apenas após invocações explícitas de #complete
, ForkJoinTask#cancel
ForkJoinTask#completeExceptionally(Throwable)
ou após a conclusão excepcional do métodocompute
. Após qualquer conclusão excepcional, a exceção pode ser retransmitida ao completador de uma tarefa (e seu completor, e assim por diante), se ela existir e ainda não tiver sido concluída. Da mesma forma, cancelar um CountedCompleter interno tem apenas um efeito local sobre esse completor, portanto, muitas vezes não é útil.
<b>Exemplos de usos.</b>
<b>Decomposição recursiva paralela.</b> CountedCompleters podem ser dispostos em árvores semelhantes às frequentemente usadas com RecursiveAction
s, embora as construções envolvidas na sua configuração normalmente variem. Aqui, o completo de cada tarefa é seu pai na árvore de computação. Mesmo que eles impliquem um pouco mais de contabilidade, CountedCompleters podem ser melhores escolhas ao aplicar uma operação possivelmente demorada (que não pode ser subdividida) a cada elemento de uma matriz ou coleção; especialmente quando a operação leva um tempo significativamente diferente para ser concluída para alguns elementos do que para outros, seja por causa de variação intrínseca (por exemplo, E/S) ou efeitos auxiliares, como coleta de lixo. Como os CountedCompleters fornecem suas próprias continuações, outras tarefas não precisam bloquear a espera para executá-las.
Por exemplo, aqui está uma versão inicial de um método utilitário que usa decomposição recursiva de divisão por dois para dividir o trabalho em partes únicas (tarefas de folha). Mesmo quando o trabalho é dividido em chamadas individuais, as técnicas baseadas em árvore geralmente são preferíveis a tarefas de forjar diretamente a folha, porque reduzem a comunicação entre roscas e melhoram o balanceamento de carga. No caso recursivo, a segunda de cada par de subtarefas a serem concluídas aciona a conclusão de seu pai (como nenhuma combinação de resultados é executada, a implementação no-op padrão do método onCompletion
não é substituída). O método utilitário configura a tarefa raiz e a invoca (aqui, implicitamente usando o ForkJoinPool#commonPool()
). É simples e confiável (mas não é o ideal) sempre definir a contagem pendente para o número de tarefas filhas e ligar tryComplete()
imediatamente antes de retornar.
{@code
public static <E> void forEach(E[] array, Consumer<E> action) {
class Task extends CountedCompleter<Void> {
final int lo, hi;
Task(Task parent, int lo, int hi) {
super(parent); this.lo = lo; this.hi = hi;
}
public void compute() {
if (hi - lo >= 2) {
int mid = (lo + hi) >>> 1;
// must set pending count before fork
setPendingCount(2);
new Task(this, mid, hi).fork(); // right child
new Task(this, lo, mid).fork(); // left child
}
else if (hi > lo)
action.accept(array[lo]);
tryComplete();
}
}
new Task(null, 0, array.length).invoke();
}}
Esse design pode ser melhorado notando que, no caso recursivo, a tarefa não tem nada a ver depois de forjar sua tarefa direita, portanto, pode invocar diretamente sua tarefa esquerda antes de retornar. (Este é um análogo da remoção de recursão de cauda.) Além disso, quando a última ação em uma tarefa é bifurcar ou invocar uma subtarefa (uma "chamada de cauda"), a chamada para tryComplete()
pode ser otimizada, ao custo de fazer a contagem pendente parecer "desativada por um".
{@code
public void compute() {
if (hi - lo >= 2) {
int mid = (lo + hi) >>> 1;
setPendingCount(1); // looks off by one, but correct!
new Task(this, mid, hi).fork(); // right child
new Task(this, lo, mid).compute(); // direct invoke
} else {
if (hi > lo)
action.accept(array[lo]);
tryComplete();
}
}}
Como uma otimização adicional, observe que a tarefa esquerda nem precisa existir. Em vez de criar um novo, podemos continuar usando a tarefa original e adicionar uma contagem pendente para cada bifurcação. Além disso, como nenhuma tarefa nessa árvore implementa um #onCompletion(CountedCompleter)
método, tryComplete
pode ser substituído por #propagateCompletion
.
{@code
public void compute() {
int n = hi - lo;
for (; n >= 2; n /= 2) {
addToPendingCount(1);
new Task(this, lo + n/2, lo + n).fork();
}
if (n > 0)
action.accept(array[lo]);
propagateCompletion();
}}
Quando as contagens pendentes podem ser pré-calculadas, elas podem ser estabelecidas no construtor:
{@code
public static <E> void forEach(E[] array, Consumer<E> action) {
class Task extends CountedCompleter<Void> {
final int lo, hi;
Task(Task parent, int lo, int hi) {
super(parent, 31 - Integer.numberOfLeadingZeros(hi - lo));
this.lo = lo; this.hi = hi;
}
public void compute() {
for (int n = hi - lo; n >= 2; n /= 2)
new Task(this, lo + n/2, lo + n).fork();
action.accept(array[lo]);
propagateCompletion();
}
}
if (array.length > 0)
new Task(null, 0, array.length).invoke();
}}
Otimizações adicionais de tais classes podem envolver classes especializadas para etapas de folha, subdividindo por digamos, quatro, em vez de duas por iteração, e usando um limiar adaptativo em vez de sempre subdividir em elementos únicos.
<b>Pesquisa.</b> Uma árvore de CountedCompleters pode procurar um valor ou propriedade em diferentes partes de uma estrutura de dados e relatar um resultado em um java.util.concurrent.atomic.AtomicReference AtomicReference
assim que um for encontrado. Os demais podem sondar o resultado para evitar trabalhos desnecessários. (Você também pode #cancel cancelar outras tarefas, mas geralmente é mais simples e eficiente apenas deixá-los notar que o resultado está definido e, em caso afirmativo, pular o processamento adicional.) Ilustrando novamente com uma matriz usando particionamento completo (novamente, na prática, as tarefas de folha quase sempre processam mais de um elemento):
{@code
class Searcher<E> extends CountedCompleter<E> {
final E[] array; final AtomicReference<E> result; final int lo, hi;
Searcher(CountedCompleter<?> p, E[] array, AtomicReference<E> result, int lo, int hi) {
super(p);
this.array = array; this.result = result; this.lo = lo; this.hi = hi;
}
public E getRawResult() { return result.get(); }
public void compute() { // similar to ForEach version 3
int l = lo, h = hi;
while (result.get() == null && h >= l) {
if (h - l >= 2) {
int mid = (l + h) >>> 1;
addToPendingCount(1);
new Searcher(this, array, result, mid, h).fork();
h = mid;
}
else {
E x = array[l];
if (matches(x) && result.compareAndSet(null, x))
quietlyCompleteRoot(); // root task is now joinable
break;
}
}
tryComplete(); // normally complete whether or not found
}
boolean matches(E e) { ... } // return true if found
public static <E> E search(E[] array) {
return new Searcher<E>(null, array, new AtomicReference<E>(), 0, array.length).invoke();
}
}}
Neste exemplo, assim como em outros em que as tarefas não têm outros efeitos a não ser um compareAndSet
resultado comum, a invocação incondicional à direita de pode ser tornada tryComplete
condicional (if (result.get() == null) tryComplete();
) porque nenhuma outra escrituração é necessária para gerenciar as conclusões depois que a tarefa raiz for concluída.
<b>Subtarefas de gravação.</b> CountedCompleter tarefas que combinam resultados de várias subtarefas geralmente precisam acessar esses resultados no método #onCompletion(CountedCompleter)
. Como ilustrado na classe a seguir (que executa uma forma simplificada de redução de mapa, onde mapeamentos e reduções são todos do tipo E
), uma maneira de fazer isso em dividir e conquistar designs é fazer com que cada subtarefa registre seu irmão, para que possa ser acessado no método onCompletion
. Esta técnica aplica-se a reduções em que a ordem de combinação de resultados à esquerda e à direita não importa; Reduções ordenadas exigem designações explícitas à esquerda/direita. Variantes de outras simplificações vistas nos exemplos acima também podem ser aplicadas.
{@code
class MyMapper<E> { E apply(E v) { ... } }
class MyReducer<E> { E apply(E x, E y) { ... } }
class MapReducer<E> extends CountedCompleter<E> {
final E[] array; final MyMapper<E> mapper;
final MyReducer<E> reducer; final int lo, hi;
MapReducer<E> sibling;
E result;
MapReducer(CountedCompleter<?> p, E[] array, MyMapper<E> mapper,
MyReducer<E> reducer, int lo, int hi) {
super(p);
this.array = array; this.mapper = mapper;
this.reducer = reducer; this.lo = lo; this.hi = hi;
}
public void compute() {
if (hi - lo >= 2) {
int mid = (lo + hi) >>> 1;
MapReducer<E> left = new MapReducer(this, array, mapper, reducer, lo, mid);
MapReducer<E> right = new MapReducer(this, array, mapper, reducer, mid, hi);
left.sibling = right;
right.sibling = left;
setPendingCount(1); // only right is pending
right.fork();
left.compute(); // directly execute left
}
else {
if (hi > lo)
result = mapper.apply(array[lo]);
tryComplete();
}
}
public void onCompletion(CountedCompleter<?> caller) {
if (caller != this) {
MapReducer<E> child = (MapReducer<E>)caller;
MapReducer<E> sib = child.sibling;
if (sib == null || sib.result == null)
result = child.result;
else
result = reducer.apply(child.result, sib.result);
}
}
public E getRawResult() { return result; }
public static <E> E mapReduce(E[] array, MyMapper<E> mapper, MyReducer<E> reducer) {
return new MapReducer<E>(null, array, mapper, reducer,
0, array.length).invoke();
}
}}
Aqui, o método onCompletion
assume uma forma comum a muitos projetos de conclusão que combinam resultados. Esse método de retorno de chamada é acionado uma vez por tarefa, em qualquer um dos dois contextos diferentes em que a contagem pendente é, ou se torna, zero: (1) por uma tarefa em si, se sua contagem pendente for zero após a invocação de tryComplete
, ou (2) por qualquer uma de suas subtarefas quando elas concluírem e reduzirem a contagem pendente para zero. O caller
argumento distingue os casos. Na maioria das vezes, quando o chamador é this
, nenhuma ação é necessária. Caso contrário, o argumento chamador pode ser usado (geralmente por meio de um cast) para fornecer um valor (e/ou links para outros valores) a ser combinado. Supondo o uso adequado de contagens pendentes, as ações dentro onCompletion
ocorrem (uma vez) após a conclusão de uma tarefa e suas subtarefas. Nenhuma sincronização adicional é necessária dentro desse método para garantir a segurança do thread de acessos a campos desta tarefa ou outras tarefas concluídas.
<b>Travessias de Conclusão.</b> Se o uso onCompletion
para processar conclusões for inaplicável ou inconveniente, você poderá usar métodos #firstComplete
e #nextComplete
criar travessias personalizadas. Por exemplo, para definir um MapReducer que apenas divide tarefas à direita na forma do terceiro exemplo ForEach, as conclusões devem reduzir cooperativamente ao longo de links de subtarefas não esgotados, o que pode ser feito da seguinte maneira:
{@code
class MapReducer<E> extends CountedCompleter<E> { // version 2
final E[] array; final MyMapper<E> mapper;
final MyReducer<E> reducer; final int lo, hi;
MapReducer<E> forks, next; // record subtask forks in list
E result;
MapReducer(CountedCompleter<?> p, E[] array, MyMapper<E> mapper,
MyReducer<E> reducer, int lo, int hi, MapReducer<E> next) {
super(p);
this.array = array; this.mapper = mapper;
this.reducer = reducer; this.lo = lo; this.hi = hi;
this.next = next;
}
public void compute() {
int l = lo, h = hi;
while (h - l >= 2) {
int mid = (l + h) >>> 1;
addToPendingCount(1);
(forks = new MapReducer(this, array, mapper, reducer, mid, h, forks)).fork();
h = mid;
}
if (h > l)
result = mapper.apply(array[l]);
// process completions by reducing along and advancing subtask links
for (CountedCompleter<?> c = firstComplete(); c != null; c = c.nextComplete()) {
for (MapReducer t = (MapReducer)c, s = t.forks; s != null; s = t.forks = s.next)
t.result = reducer.apply(t.result, s.result);
}
}
public E getRawResult() { return result; }
public static <E> E mapReduce(E[] array, MyMapper<E> mapper, MyReducer<E> reducer) {
return new MapReducer<E>(null, array, mapper, reducer,
0, array.length, null).invoke();
}
}}
<b>Gatilhos.</b> Alguns CountedCompleters nunca são bifurcados, mas servem como pedaços de encanamento em outros projetos, incluindo aqueles em que a conclusão de uma ou mais tarefas assíncronas aciona outra tarefa assíncrona. Por exemplo:
{@code
class HeaderBuilder extends CountedCompleter<...> { ... }
class BodyBuilder extends CountedCompleter<...> { ... }
class PacketSender extends CountedCompleter<...> {
PacketSender(...) { super(null, 1); ... } // trigger on second completion
public void compute() { } // never called
public void onCompletion(CountedCompleter<?> caller) { sendPacket(); }
}
// sample use:
PacketSender p = new PacketSender();
new HeaderBuilder(p, ...).fork();
new BodyBuilder(p, ...).fork();}
Adicionado em 1.8.
Documentação Java para java.util.concurrent.CountedCompleter
.
Partes desta página são modificações baseadas no trabalho criado e compartilhado pelo Android Open Source Project e usado de acordo com os termos descritos na Creative Commons 2.5 Attribution License.
Construtores
CountedCompleter() |
Cria um novo CountedCompleter sem completador e uma contagem pendente inicial de zero. |
CountedCompleter(CountedCompleter) |
Cria um novo CountedCompleter com o complete fornecido e uma contagem pendente inicial de zero. |
CountedCompleter(CountedCompleter, Int32) |
Cria um novo CountedCompleter com o completo fornecido e a contagem pendente inicial. |
CountedCompleter(IntPtr, JniHandleOwnership) |
A |
Propriedades
Class |
Retorna a classe de tempo de execução deste |
Completer |
Retorna o completer estabelecido no construtor desta tarefa, ou |
Exception |
Retorna a exceção lançada pela computação base, ou um se cancelado, ou |
ForkJoinTaskTag |
Retorna a marca para esta tarefa. (Herdado de ForkJoinTask) |
Handle |
O identificador para a instância subjacente do Android. (Herdado de Object) |
IsCancelled |
Retorna |
IsCompletedAbnormally |
Retorna |
IsCompletedNormally |
Retorna |
IsDone |
Retorna |
JniIdentityHashCode |
A |
JniPeerMembers |
A |
PeerReference |
A |
PendingCount |
Retorna a contagem pendente atual. -ou- Define a contagem pendente para o valor determinado. |
RawRawResult |
Retorna o resultado que seria retornado pelo Join(), mesmo se essa tarefa foi concluída de forma anormal ou |
RawResult |
Retorna o resultado da computação. |
Root |
Retorna a raiz da computação atual; eu. |
ThresholdClass |
A |
ThresholdType |
A |
Métodos
AddToPendingCount(Int32) |
Adiciona (atomicamente) o valor dado à contagem pendente. |
Cancel(Boolean) |
Tenta cancelar a execução desta tarefa. (Herdado de ForkJoinTask) |
Clone() |
Cria e retorna uma cópia desse objeto. (Herdado de Object) |
CompareAndSetForkJoinTaskTag(Int16, Int16) |
Atomicamente define condicionalmente o valor da tag para esta tarefa. (Herdado de ForkJoinTask) |
CompareAndSetPendingCount(Int32, Int32) |
Define (atomicamente) a contagem pendente para a contagem dada somente se ela atualmente mantém o valor esperado dado. |
Complete(Object) |
Independentemente da contagem pendente, invoca |
CompleteExceptionally(Throwable) |
Conclui essa tarefa de forma anormal e, se ainda não tiver sido abortada ou cancelada, fará com que ela lance a exceção dada sobre |
Compute() |
O principal cálculo realizado por esta tarefa. |
DecrementPendingCountUnlessZero() |
Se a contagem pendente for diferente de zero, (atomicamente) a diminui. |
Dispose() |
A |
Dispose(Boolean) |
A |
Equals(Object) |
Indica se algum outro objeto é "igual" a este. (Herdado de Object) |
Exec() |
Implementa convenções de execução para CountedCompleters. |
FirstComplete() |
Se a contagem pendente dessa tarefa for zero, retornará essa tarefa; caso contrário, diminui sua contagem pendente e devolve. |
Fork() |
Organiza a execução assíncrona dessa tarefa no pool em que a tarefa atual está sendo executada, se aplicável, ou usando o |
Get() |
Aguarda, se necessário, que a computação seja concluída e, em seguida, recupera seu resultado. (Herdado de ForkJoinTask) |
Get(Int64, TimeUnit) |
Aguarda, se necessário, pelo máximo o tempo determinado para que a computação seja concluída e, em seguida, recupera seu resultado, se disponível. (Herdado de ForkJoinTask) |
GetHashCode() |
Retorna um valor de código hash para o objeto. (Herdado de Object) |
HelpComplete(Int32) |
Se essa tarefa não tiver sido concluída, tentará processar no máximo o número determinado de outras tarefas não processadas para as quais essa tarefa está no caminho de conclusão, se houver alguma. |
Invoke() |
Inicia a execução dessa tarefa, aguarda sua conclusão, se necessário, e retorna seu resultado, ou lança um (desmarcado) |
JavaFinalize() |
Chamado pelo coletor de lixo em um objeto quando a coleta de lixo determina que não há mais referências ao objeto. (Herdado de Object) |
Join() |
Retorna o resultado da computação quando #isDone é concluído. (Herdado de ForkJoinTask) |
NextComplete() |
Se essa tarefa não tiver um completo, invocará |
Notify() |
Ativa um único thread que está aguardando no monitor deste objeto. (Herdado de Object) |
NotifyAll() |
Ativa todos os threads que estão aguardando no monitor deste objeto. (Herdado de Object) |
OnCompletion(CountedCompleter) |
Executa uma ação quando o método |
OnExceptionalCompletion(Throwable, CountedCompleter) |
Executa uma ação quando o método |
PropagateCompletion() |
Equivalente a |
QuietlyComplete() |
Conclui esta tarefa normalmente sem definir um valor. (Herdado de ForkJoinTask) |
QuietlyCompleteRoot() |
Equivalente a |
QuietlyInvoke() |
Inicia a execução desta tarefa e aguarda sua conclusão se necessário, sem retornar seu resultado ou lançar sua exceção. (Herdado de ForkJoinTask) |
QuietlyJoin() |
Junta-se a esta tarefa, sem devolver o seu resultado ou lançar a sua excepção. (Herdado de ForkJoinTask) |
Reinitialize() |
Redefine o estado de escrituração interna desta tarefa, permitindo um |
SetForkJoinTaskTag(Int16) |
Atomicamente define o valor da tag para essa tarefa e retorna o valor antigo. (Herdado de ForkJoinTask) |
SetHandle(IntPtr, JniHandleOwnership) |
Define a propriedade Handle. (Herdado de Object) |
SetRawResult(Object) |
Um método que CountedCompleters com resultados pode opcionalmente usar para ajudar a manter os dados de resultados. |
ToArray<T>() |
A |
ToString() |
Retorna uma representação de cadeia de caracteres do objeto. (Herdado de Object) |
TryComplete() |
Se a contagem pendente for diferente de zero, diminui a contagem; caso contrário, invoca |
TryUnfork() |
Tenta desagendar esta tarefa para execução. (Herdado de ForkJoinTask) |
UnregisterFromRuntime() |
A |
Wait() |
Faz com que o thread atual aguarde até que ele seja ativado, normalmente sendo <em notificado</em> ou <em>interrompido</em>>. (Herdado de Object) |
Wait(Int64) |
Faz com que o thread atual aguarde até que ele seja despertado, normalmente sendo <em>notificado</em> ou <em interrompido</em>, ou até que>uma certa quantidade de tempo real tenha decorrido. (Herdado de Object) |
Wait(Int64, Int32) |
Faz com que o thread atual aguarde até que ele seja despertado, normalmente sendo <em>notificado</em> ou <em interrompido</em>, ou até que>uma certa quantidade de tempo real tenha decorrido. (Herdado de Object) |
Implantações explícitas de interface
IJavaPeerable.Disposed() |
A |
IJavaPeerable.DisposeUnlessReferenced() |
A |
IJavaPeerable.Finalized() |
A |
IJavaPeerable.JniManagedPeerState |
A |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
A |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
A |
IJavaPeerable.SetPeerReference(JniObjectReference) |
A |
Métodos de Extensão
JavaCast<TResult>(IJavaObject) |
Executa uma conversão de tipo verificada em tempo de execução do Android. |
JavaCast<TResult>(IJavaObject) |
A |
GetJniTypeName(IJavaPeerable) |
A |
GetAsync(IFuture) |
A |
GetAsync(IFuture, Int64, TimeUnit) |
A |