登录然后以线程安全的方式发出请求

时间:2016-05-12 18:34:21

标签: java multithreading rest concurrency

我正在使用Java v1.7和Spring Boot v1.3.3.RELEASE。我正在尝试编写一个会触及需要身份验证的休息端点的类。因此,每次我希望在请求之间存储凭据时,我都不会登录。如果我正在使用的会话已过期,我想重新登录,然后再试一次。

的伪代码:

try
{
    getData(credentials);
}
catch (UnauthorizedException e)
{
    credentials = login(); // Multiple threads could get to this point
    getData(credentials);
}

但是,这段代码是多线程的,我正在努力弄清楚如何防止创建太多会话。

欢迎提示。

2 个答案:

答案 0 :(得分:1)

如果由于其他原因每次重新抛出该异常,您将需要确保不会永远循环,但这应该有效:

for (;;) {
    Credentials local = credentials;
    try {
        getData(local);
        break;
    }
    catch (UnauthorizedException e) {
        synchronized (this) {
            if (credentials == local) {
                credentials = login();
            }
        }
    }
}

只有一个线程应该能够调用login方法。其他线程将在synchronized块中等待,然后意识到它已被另一个线程更新并重试getData()。

答案 1 :(得分:0)

我认为您必须同步对login方法的访问,因此只有一个线程可以访问它并设置凭据。如果另一个线程要输入,则必须等待,然后由已经锁定锁的线程设置凭证。

伪码:

try {
    getData(credentials);
} catch (UnauthorizedException e) {
    synchronize(lockObject) {
        if (credentials == null) {
            credentials = login();
            getData(credentials);
        }
    }
}

除此之外,您必须将凭据设置为null,以确保if将起作用。