У меня есть несколько потоков, которые выполняют одну и ту же задачу снова и снова. В этой задаче он должен повторно аутентифицироваться с помощью службы для получения нового сеанса. Но происходит то, что все потоки пытаются повторно аутентифицировать.Многопоточный метод
Я хочу сделать так, чтобы прошла повторная проверка подлинности первого потока, а остальные ждут завершения и продолжения, как обычно.
Это мой оригинальный код проверки перед внедрением решения:
public class Main {
public static void main(String args[]){
new Main();
}
public Main(){
AuthManager authClass = new AuthManager();
for (int i = 0; i < 5; i++) {
Thread thr = new Thread(() -> {
int count = 0;
while(count < 2) { // Bad practice but just for the example.
if(count == 1){
if(authClass.reAuthenticate()) {
System.out.println("Reauthenticated.");
authClass.doStuff();
}
} else {
authClass.doStuff();
}
count++;
}
});
thr.start();
}
// Keep the program running for 30 seconds.
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
// ignored
}
}
private class AuthManager {
public boolean reAuthenticate(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}
System.out.println("Reauthenticating..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}
return true; // or false when no success in the real application.
}
public void doStuff(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}
System.out.println("Doing stuff.");
}
}
}
Ответ:
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Reauthenticating..
Reauthenticating..
Reauthenticating..
Reauthenticating..
Reauthenticating..
Reauthenticated.
Reauthenticated.
Reauthenticated.
Reauthenticated.
Reauthenticated.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Ответ Я хочу:
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Reauthenticating..
Reauthenticated.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Как я могу добиться этого?
Редактировать Я сделал это сейчас с ответом @haifzhan, но это не будет работать, когда я должен проверить подлинность позже.
public class Main {
public static void main(String args[]){
new Main();
}
public Main(){
AuthManager authClass = new AuthManager();
for (int i = 0; i < 5; i++) {
Thread thr = new Thread(() -> {
int count = 0;
while(count < 4) { // Bad practice but just for the example.
if(count == 1 || count == 3){
if(authClass.reAuthenticate()) {
System.out.println("Reauthenticated.");
authClass.doStuff();
}
} else {
authClass.doStuff();
}
count++;
}
});
thr.start();
}
// Keep the program running for 30 seconds.
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
// ignored
}
}
private class AuthManager {
private final AtomicBoolean isAuthorized = new AtomicBoolean();
public synchronized boolean reAuthenticate() {
if(!isAuthorized.get()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}
System.out.println("Reauthenticating..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}
isAuthorized.set(true);
return isAuthorized.get();
}
return isAuthorized.get();
}
public void doStuff(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}
System.out.println("Doing stuff.");
}
}
}
Ответ:
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Reauthenticating..
Reauthenticated.
Reauthenticated.
Reauthenticated.
Reauthenticated.
Reauthenticated.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Reauthenticated.
Doing stuff.
Reauthenticated.
Doing stuff.
Reauthenticated.
Doing stuff.
Reauthenticated.
Doing stuff.
Reauthenticated.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Ответ Я хочу:
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Reauthenticating..
Reauthenticated.
Reauthenticated.
Reauthenticated.
Reauthenticated.
Reauthenticated.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Reauthenticating..
Reauthenticated.
Reauthenticated.
Reauthenticated.
Reauthenticated.
Reauthenticated.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Doing stuff.
Вы сделали 5 потоков, которые делают то же самое (переутверждайте и делайте что-нибудь), вы должны попытаться сделать только один поток, который аутентифицируется, и другие, которые только делают вещи, или попытаются проверить, прошел ли поток уже аутентифицирован и в этом случае пропустить reauthenticate stuff. – aleb2000
@ aleb2000 имеет хороший момент, но если вы упрям, существуют различные способы сокращения доступа к ресурсу, например - [Семафоры] (https://docs.oracle.com/javase/7/docs/api/java/ Util/параллельный/Semaphore.html). Просто помните, что это добавляет сложности. – zec
Я не знал о Семафорах, да, правильно использовал это. @ Zec – aleb2000