2017-06-20 119 views
6

我有一个webservice调用来获取授权令牌并将其用于后续的webservice调用。现在我们前面所做的是每当我们进行任何Web服务调用时,我们首先创建令牌Web服务,然后调用实际的Web服务。制作静态方法是否同步

获取令牌的方法如下所示。基本上这个代码所做的就是调用Web服务来获取令牌,并使用GSON解析响应并获取令牌。

public static String getAuthTicket() { 
    String authTicket = null; 
    HttpResponse httpResponse = getAuthResponse(); 
    String body; 
    if (httpResponse.getStatusLine().getStatusCode() == 200) { 
    try { 
     body = IOUtils.toString(httpResponse.getEntity().getContent()); 
     Gson gson = new GsonBuilder().disableHtmlEscaping().create(); 
     ResponseTicket responseTicket = gson.fromJson(body, ResponseTicket.class); 
     authTicket = responseTicket.getTicket(); 
    } catch (UnsupportedOperationException e) { 
     LOGGER.error("UnsupportedOperationException : ",e); 
    } catch (IOException e) { 
     LOGGER.error("IO Exception : ",e); 
    } 
    } 
    return authTicket; 
} 

这显然导致了性能问题。因此,提供Web服务来获取令牌的一方已经使该令牌有效30分钟。

因此,在上述方法中,我们所考虑的是将令牌与时间一起放入缓存中,并检查当前时间 - 缓存时间是否小于30.如果时间大于30,我们将进行服务调用获取令牌并用缓存中的时间戳更新令牌。

唯一让我担心的是关于同步,这样我就不会因为竞争条件而受到腐败。

我在想这个静态方法是同步的。你认为还有没有其他更好的方法?

+3

两种操作之间的竞争条件? –

+0

在进行任何后续Web服务调用之前获取身份验证令牌的争用条件 – noob

+0

您在哪里存储/缓存身份验证令牌? – Markus

回答

7

答案是:它取决于

当多个线程在同一时间点访问共享数据时出现竞争条件。所以,当你将有代码,如:

private final Map<X, Y> sharedCache = new HashMap<>(); 

public static getAuthTicket() { 
    if (! sharedCache.containsKey...) { 
    sharedCache.put(... 
... 

你会受到竞态条件 - 两个线程可以在同一时间进来,而且在同样的时间共享的地图更新;导致各种问题。

当我收到你的代码的权利 - 你将有类似的东西:

private static String cachedToken = null; 

public static getAuthTicket() { 
    if (cachedToken == null || isTooOld(cachedToken)) { 
    cachedToken = getAuthTicketForReal(); 
    } 
    return cachedToken; 
} 

你可能不希望两个线程并行调用getAuthTicketForReal()

所以,是的,使该方法同步是一种有效的方法。

其中:真正的问题是:是否足够添加该关键字?鉴于我的代码 - 答案是肯定的。你只是想避免这个缓存由​​多个线程“并行”设置。

最后:如果您担心在这里使用同步的性能影响 - 请简单地忘记这一点。您正在谈论多秒“基于网络”的操作;所以你绝对不必担心同步可能有的毫秒开销(组成这个数字 - 关键的事情:它太小了,以至于在你正在进行的操作中无关紧要)。

关于您的评论:当然,使用同步意味着JVM将序列调用该方法。这意味着此方法需要1分钟才能返回 - 对该方法的任何其他调用将在该1分钟内

从这个意义上说,研究如何编写此方法的方法可能是一种很好的练习方法,其方法级别为而非要求同步。例如,通过使用可处理多个线程的数据结构来操作它们。

+0

谢谢。我会将其标记为答案。我只是害怕,因为我的教授告诉我,同步访问任何内容的持续时间应该像访问您的姻亲之家。它应该尽可能短以避免问题。 – noob