多线程同步两个方法java

时间:2014-06-14 12:10:44

标签: java multithreading asynchronous

我有一个多线程服务器,请求即将到达服务器。 我们有两种类型的客户端。

一个是客户 其他是管理员

客户可以发送请求 客户可以取消请求 管理员可以接受请求

有两种不同的功能

一个是取消请求功能,即方法A. 另一种是接受请求函数,即方法B

客户要求将其标记为待处理。 现在管理员回复接受,同时客户取消

所以管理员认为他接受了这个请求 并且客户认为他取消了请求。

所以无论如何都要同步取消和接受方法。

//Cancel Request
public void A() {
    int currentrequeststate = app.sharedData().getMap("users").get(user_id); //let say this is read as pending
    if (currentrequeststate == RequestState.PENDING) {
        currentrequeststate = RequestState.CANCEL;
        app.sharedData().getMap("users").put(user_id, currentrequeststate);
        //cancel it and sending cancel message
    }
}


//Accept Request
public void B() {
    int currentrequeststate = app.sharedData().getMap("users").get(user_id); //there is a chance this also read as pending
    if (currentrequeststate == RequestState.CANCEL) {
        //sending no trip to accept might be canceled
    } else {
        currentrequeststate = RequestState.ACCEPTED;
        app.sharedData().getMap("users").put(user_id, currentrequeststate);
        //Accept it and sending accept message
    }
}

因为会有多个线程,并且这两个方法可以由不同的线程同时运行。 所以两种方法都有可能将当前currentrequeststate读取为pending 第一个方法A将取消请求 第二个方法B将接受请求

1 个答案:

答案 0 :(得分:0)

我并不完全熟悉你所遇到的确切问题 解决但我会尝试下面的这些方面。

  1. 我会使用str类型的数组String[1]作为状态,而不仅仅是String s;这样我就不会改变我同步的引用str(我改变的是String指向的str[0]对象。

  2. 这也允许我通过不同的线程同时执行两个方法A,如果它们位于不同user_id的上下文中。我的同步仅在str,即每user_id。如果他们要求不同的A,我不会阻止user_id上的线程。实际上我认为user_id应该是这两种方法的参数。

  3. 注意我如何比较字符串(使用等号,而不是==)

  4. 我认为RequestState中的PENDING,ACCEPTED,CANCELED等常量是字符串。如果这个假设不正确,只需按照相同的逻辑稍微修改代码。

    // Cancel Request
    public void A() {
        String[] str = app.sharedData().getMap("users").get(user_id);
        synchronized(str){
            String currentrequeststate = str[0];
            if (RequestState.PENDING.equals(currentrequeststate) {
                str[0] = RequestState.CANCELLED;
                // cancel it and sending cancel message
            }else if (RequestState.ACCEPTED.equals(currentrequeststate)){
                // throw exception here (or take whatever action appropriate)
                // as this request was already accepted by the admin;
                // so it is too late for the user to cancel it
            }
        }
    }
    
    
    // Accept Request
    public void B() {
        String[] str = app.sharedData().getMap("users").get(user_id);
        synchronized(str){
            String currentrequeststate = str[0];
            if (RequestState.CANCELLED.equals(currentrequeststate)) {
                // Already cancelled, admin cannot accept it now as it's too late;
                // so take whatever action is appropriate in this case
            } else {
                str[0] = RequestState.ACCEPTED;
                // OK, accept it and sending accept message
            }
        }
    }