获取和释放锁的困惑

时间:2014-04-14 14:48:36

标签: java android locks

我有来自Android模拟器客户端的以下代码段:

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder) {
    String key = selection;     
    String keyHash = genHash(key);
    Log.v("provider.query","Key & keyHash: "+key+" & "+keyHash);
    if(SimpleDhtUtil.toForward(keyHash, currentHash, predecessorHash)){
        DhtDto dto = new QueryTransfer(successorPort, currentPort, -1, key, keyHash);
        st.makeSendRequest(dto);
        synchronized(BigLock.LOCK){
            SimpleDhtUtil.cursorReset();
            requiredAnswers = 1;
            currentAnswers = 0;
        }   
        while(requiredAnswers>currentAnswers){
            synchronized(BigLock.LOCK){

                try{
                    if(requiredAnswers>currentAnswers){
                        Log.d("provider.externalQueryLock","CA: "+currentAnswers+"RA: "+requiredAnswers+" Waiting... "+BigLock.LOCK);
                        BigLock.LOCK.wait();
                        Log.d("provider.externalQueryLock","Woke up");
                    }
            }catch(InterruptedException e){
                Log.e("provider.query", "InterruptedException",e);
            }
        }
    }
    return SimpleDhtUtil.getCursor();
}

以下代码在同一AVD的服务器中:

private void acceptAnswer(QueryAcknowledge qa) {                
//  Object lock = SimpleDhtProvider.externalQueryLock;
    synchronized(BigLock.LOCK){
        SimpleDhtProvider.currentAnswers += 1;
        Log.d("ReceiverTask.acceptAnswer","Got result. Current count: "+SimpleDhtProvider.currentAnswers);
        SimpleDhtUtil.addValues(qa.getRecords());
        Log.d("ReceiverTask.acceptAnswer","Aggregated result. Net count: "+SimpleDhtUtil.getCursor().getCount());       
        BigLock.LOCK.notifyAll();
        Log.d("ReceiverTask.acceptAnswer","lock released: "+BigLock.LOCK);
    }       
}

现在的问题是,当在服务器代码中释放锁时,我希望通知并唤醒客户端中的锁。这种情况发生在> 80%的时间。但有时它会卡住。找到下面的android日志。此外,currentAnswers和requiredAnswers始终从客户端处理,即,这些变量在Client中是静态和易变的,而BigLock是一个枚举,只有一个值为LOCK。

客户日志:

04-14 08:14:07.172: V/provider.query(2699): Key & keyHash: 6oLNUimWIuAM4YWN183cwtz0te5aq6r7 & 837cccd1cac03a9c4c9169fad595a997d2673920
04-14 08:14:07.202: D/provider.externalQueryLock(2699): CA: 0RA: 1 Waiting... LOCK

服务器日志:

04-14 08:14:07.192: D/ReceiverTask.acceptAnswer(2699): Got result. Current count: 2
04-14 08:14:07.192: D/ReceiverTask.acceptAnswer(2699): Aggregated result. Net count: 2
04-14 08:14:07.192: D/ReceiverTask.acceptAnswer(2699): lock released: LOCK

1 个答案:

答案 0 :(得分:0)

这里的问题是我在从客户端发送请求后重置了光标,假设服务器在下一行重置光标后会收到回复。

正确的顺序是先重置光标然后发送请求。