我有一些反复执行相同任务的线程。在这个任务中,它必须重新验证服务以获得新的会话密钥。但是会发生什么,所有线程都会尝试重新进行验证。多线程方法
我想这样做,以便第一个线程重新认证通过,其他人等待完成,然后像往常一样继续。
这是实施解决方案之前,我原来的测试代码:
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个线程做同样的事情(重新认证和做的东西),你应该尝试只做一个线程认证和其他人只做东西或尝试检查线程是否已经认证,在这种情况下跳过重新认证的东西。 – aleb2000
@ aleb2000有一个好处,但如果你固执己见,有各种方法可以减少对资源的访问,如 - [Semaphores](https://docs.oracle.com/javase/7/docs/api/java/ UTIL /并发/ Semaphore.html)。只要记住它会增加复杂性。 – zec
我不知道信号量,是以正确的方式工作。@ zec – aleb2000