【发布时间】:2016-10-14 19:52:29
【问题描述】:
我必须调用一个需要验证令牌的外部 API。调用 API 的应用程序将被线程化。此外,只允许 5 个并发连接。我将使用固定线程池进行连接,但在弄清楚如何处理过期/无效令牌时遇到了问题。我想要做的是,当一个线程遇到过期令牌时,阻止其他线程获取令牌,直到它被刷新。我正在考虑使用 ReentrantLock 来执行此操作,但我不确定我的实现是否正确。
public static void main(String[] args){
for(int i = 0; i < 100; i++){
new Thread(new LockTest()).start();
}
}
public void testLock(String message) throws InterruptedException{
try{
getToken(message);
/*
* Use token here
*/
Thread.sleep(1000);
Random r = new Random();
int num = r.nextInt((25-0) + 1);
if(num == 1){ //testing only - exception thrown randomly.
throw new Exception("Token Expired!");
}
System.out.println("Message: " + message);
}catch(Exception e){
System.err.println(e.getMessage());
awaitTokenRefresh = true;
refreshToken();
}
}
private void refreshToken() throws InterruptedException {
lock.lock();
try{
System.out.println("Refreshing token...");
Thread.sleep(2000l);
System.out.println("Refreshed!");
awaitTokenRefresh = false;
awaitRefresh.signalAll();
}
finally{
lock.unlock();
}
}
//test use case for salesforce token
private void getToken(String message) throws InterruptedException {
lock.lock();
try{
while(awaitTokenRefresh){
System.out.println(message + " waiting for token refresh...");
awaitRefresh.await();
}
}
finally{
lock.unlock();
}
}
public void run(){
try {
System.out.println("Starting thread...");
testLock(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
只是为了测试,我已经进行了一些睡眠来模拟正在完成的工作。我不知道的主要事情是,当线程 A 在 getToken() 内部解锁时,线程 B 进入,但我们还不知道令牌是否无效。所以 B 实际上可能得到了 A 必须找到的错误令牌。有没有好的方法来处理这个?还是使用锁的想法完全错误?
【问题讨论】:
标签: java multithreading locking