requestsBeingProcessed

requestsBeingProcessed

我有一个访问缓存的Jersey REST服务方法。此方法跟踪requestsBeingProcessed,因为MessageService会定期更新缓存,但是只有在没有正在处理的请求时才可以这样做。递增和递减正在处理的请求数的调用是同步的,以确保线程安全的访问。

class TeamInfoService {
    @GET
    @Path("/{teamId}")
    @Produces(MediaType.TEXT_PLAIN)
    public String getTeamInfo(@PathParam("teamId") final int teamId) {
        MessageService.incrementRequestsBeingProcessed;
        String team = teamCache.getTeams().get(teamId);
        MessageService.decrementRequestsBeingProcessed;
        return team;
    }
}

class MessageService {
    private static int requestsBeingProcessed = 0;

    public synchronized static void incrementRequestsBeingProcessed() {
        requestsBeingProcessed++;
    }

    public synchronized static void decrementRequestsBeingProcessed() {
        requestsBeingProcessed--;
    }

    public synchronized static void getRequestsBeingProcessed() {
        return requestsBeingProcessed;
    }
}

问题在于MessageService必须获取锁才能更新缓存,但是只能通过检查requestsBeingProcessed来更新它,一次只能由一个线程访问。
public synchronized static void updateCache(String message) {
    while(getRequestsBeingProcessed() != 0) {
        //wait until there are no requests being processed
    }
    processMessage(message);
}

我在这里遇到了鸡/蛋的情况:我无法获取更新requestsBeingProcessed的锁,因为需要使用锁来检查requestsBeingProcessed。我应该采用其他方法解决这个问题吗?

最佳答案

每当队列中没有任何项目时,您需要通知更新线程:

public synchronized static void decrementRequestsBeingProcessed() {
        if (requestsBeingProcessed > 0) requestsBeingProcessed--;
        if (requestsBeingProcessed == 0) MessageService.class.notifyAll();
}

public synchronized static void updateCache(String message) {
    try {
       while(getRequestsBeingProcessed() != 0) {
        MessageService.class.wait();
       }
       processMessage(message);
    } catch (InterruptedException ie) {
      // devise cancellation strategy here...
    }

}

09-05 02:00