Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何知道For循环中的所有异步操作何时完成?_Java_Gwt - Fatal编程技术网

Java 如何知道For循环中的所有异步操作何时完成?

Java 如何知道For循环中的所有异步操作何时完成?,java,gwt,Java,Gwt,我在列表上有一个for循环: boolean initialized = false for(final Share share : shares) { someInstance.check(new someCallback() { @Override public void onSuccess() { // do something } }); } initialized = true;

我在列表上有一个for循环:

boolean initialized = false
for(final Share share : shares) {

    someInstance.check(new someCallback() {
        @Override
        public void onSuccess() {
            // do something
        }
    });         
}
initialized = true;
在每个步骤中,都会执行一个称为check()的异步操作。我想在所有check()操作完成后设置initialized=true。 在Java/GWT中有没有一种方法可以做到这一点


我如何知道For循环中的所有异步操作何时完成?

每次调用
onSuccess
时,只需增加一些共享计数器,计算完成的数量。你知道你已经开始了多少次(比如N),所以一旦
完成的计数器达到相同的值(N),你就知道它们都完成了。然后最后一个完成的将设置
initialized=true

我不知道GWT是否有任何特殊的限制,但是您可以等到它们都成功了,例如使用一个简单的
倒计时闩锁

    final CountDownLatch latch = new CountDownLatch(shares.size());
    for(final Share share : shares) {
        someInstance.check(new someCallback() {
            @Override
            public void onSuccess() {
                latch.countDown();
                // do something
            }
        });         
    }
    latch.await();
    boolean initalized = true;

这将简单地阻止执行,直到每个回调都倒计时一次。但阻塞通常是个坏主意。因此,您可能还需要同步设置
初始化
。并在其为真时使用一些回调。

您可以使用此回调计数器实现。当所有回调完成时,它将激发提供的异步回调。类似于Promise.all()的东西。此实现具有锁定和解锁方法,以确保某些回调在必要时才进行反击

以下是如何使用它:

CallbackCounter counter = new CallbackCounter(yourFinalCallback);
//counter.lock(); call this if methodWithCallback may execute callback synchronously
for (int i = 0; i < 10; i++)
{
    AsyncCallback<Void> counterCallback = counter.async();
    methodWithCallback(i, counterCallback);
}
//counter.unlock();
CallbackCounter=newcallbackcounter(yourlfinalcallback);
//counter.lock();如果methodWithCallback可以同步执行回调,则调用此函数
对于(int i=0;i<10;i++)
{
AsyncCallback counterCallback=counter.async();
methodWithCallback(i,反向回调);
}
//counter.unlock();
这是CallbackCounter类:

public class CallbackCounter
{

    private int count;
    private int maxCount;
    private boolean failOnError;
    private Throwable exceptionDuringLock;

    private boolean unlocked;
    private AsyncCallback<Void> callback;

    public CallbackCounter(AsyncCallback<Void> callback)
    {
        this(true, callback);
    }

    public CallbackCounter(boolean failOnError, AsyncCallback<Void> callback)
    {
        this.failOnError = failOnError;
        this.callback = callback;

        count = 0;
        maxCount = 0;
        unlocked = true;
    }

    public int getCount()
    {
        return maxCount;
    }

    public LocalDatabaseRemoveCallback localDatabaseRemove()
    {
        maxCount++;

        return new LocalDatabaseRemoveCallback()
        {
            @Override
            public void onRemove(String key)
            {
                counterSuccess();
            }

            @Override
            public void onError(String key, Throwable error)
            {
                counterFail(error);
            }
        };
    }

    public AsyncCallback<Void> async()
    {
        maxCount++;

        return new AsyncCallback<Void>()
        {
            @Override
            public void onSuccess(Void result)
            {
                counterSuccess();
            }

            @Override
            public void onFailure(Throwable caught)
            {
                counterFail(caught);
            }
        };
    }

    public CommandCallback<Void> command()
    {
        maxCount++;

        return new CommandCallback<Void>()
        {
            @Override
            public void onCallback(Void data)
            {
                counterSuccess();
            }
        };
    }

    public SimpleCallback simple()
    {
        maxCount++;

        return new SimpleCallback()
        {
            @Override
            public void onCallback()
            {
                counterSuccess();
            }
        };
    }

    public void lock()
    {
        if (unlocked)
        {
            unlocked = false;
        }
    }

    public void unlock()
    {
        if (!unlocked)
        {
            unlocked = true;

            if (count >= maxCount)
            {
                if (exceptionDuringLock == null)
                {
                    conterSuccessCallback();
                }
                else
                {
                    Throwable e = exceptionDuringLock;
                    exceptionDuringLock = null;

                    conterFailCallback(e);
                }
            }
        }
    }

    private void counterSuccess()
    {
        count++;

        if (!unlocked)
        {
            return;
        }

        if (count >= maxCount)
        {
            conterSuccessCallback();
        }
    }

    private void conterSuccessCallback()
    {
        if (callback != null)
        {
            AsyncCallback<Void> callbackToCall = callback;
            callback = null;

            callbackToCall.onSuccess(null);
        }
    }

    private void counterFail(Throwable caught)
    {
        count++;

        if (failOnError)
        {
            if (unlocked)
            {
                conterFailCallback(caught);
            }
            else
            {
                exceptionDuringLock = caught;
            }
        }
    }

    private void conterFailCallback(Throwable caught)
    {
        if (callback != null)
        {
            AsyncCallback<Void> callbackToCall = callback;
            callback = null;

            callbackToCall.onFailure(caught);
        }
    }
}
公共类回调计数器
{
私人整数计数;
私有整数最大计数;
私有布尔故障诊断错误;
私用一次性锁;
私有布尔解锁;
私有异步回调;
公共回调计数器(异步回调)
{
这(对,回调);
}
公共回调计数器(布尔failOnError、异步回调)
{
this.failOnError=failOnError;
this.callback=回调;
计数=0;
最大计数=0;
解锁=真;
}
public int getCount()
{
返回最大计数;
}
公共LocalDatabaseRemoveCallback localDatabaseRemove()
{
maxCount++;
返回新的LocalDatabaseRemoveCallback()
{
@凌驾
移除时的公共void(字符串键)
{
反成功();
}
@凌驾
public void onError(字符串键,可丢弃错误)
{
反邮件(错误);
}
};
}
公共异步回调异步()
{
maxCount++;
返回新的AsyncCallback()
{
@凌驾
成功时公开作废(作废结果)
{
反成功();
}
@凌驾
失败时的公共无效(可丢弃)
{
反帆(被抓住);
}
};
}
公共命令回调命令()
{
maxCount++;
返回新的CommandCallback()
{
@凌驾
公共void onCallback(void数据)
{
反成功();
}
};
}
public SimpleCallback simple()
{
maxCount++;
返回新的SimpleCallback()
{
@凌驾
public void onCallback()
{
反成功();
}
};
}
公共无效锁()
{
如果(未锁定)
{
解锁=假;
}
}
公开作废解锁()
{
如果(!解锁)
{
解锁=真;
如果(计数>=最大计数)
{
如果(例外DuringLock==null)
{
contertSuccessCallback();
}
其他的
{
可丢弃的e=例外的DuringLock;
exceptionDuringLock=null;
contertfail(e);
}
}
}
}
私有无效反成功()
{
计数++;
如果(!解锁)
{
返回;
}
如果(计数>=最大计数)
{
contertSuccessCallback();
}
}
私有void contersuccescallback()
{
if(回调!=null)
{
AsyncCallback callbackToCall=回调;
callback=null;
callbackToCall.onSuccess(空);
}
}
私人空位反帆(可丢弃)
{
计数++;
如果(失败者错误)
{
如果(未锁定)
{
contertfailcallback(捕获);
}
其他的
{
exceptionDuringLock=捕获;
}
}
}
私有void conterFailCallback(可丢弃捕获)
{
if(回调!=null)
{
AsyncCallback callbackToCall=回调;
callback=null;
callbackToCall.onFailure(捕获);
}
}
}

someCallback是接口还是类?如果是一个类,您可以添加一个静态布尔方法
processedAll()
或其他东西,以及一个静态
someCallback[]
。该方法在数组中循环,检查以确保每个数组都已完成。实际上有几种方法可以做到这一点。如果知道
someCallback
是一个类还是一个接口,或者倒计时到0,那就很好了,这样除了初始化计数器的位置之外,什么都不需要知道一个幻数。@zapl是的,那就更好了。