【问题标题】:confusion in acquiring and releasing of locks获取和释放锁的混乱
【发布时间】:2014-04-14 14:48:36
【问题描述】:

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

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的Server中:

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

【问题讨论】:

    标签: java android locks


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-27
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      • 2010-11-08
      • 2013-06-18
      相关资源
      最近更新 更多