gpt4 book ai didi

java - 多线程方法

转载 作者:行者123 更新时间:2023-12-01 18:05:54 25 4
gpt4 key购买 nike

我有几个线程正在运行,它们一遍又一遍地执行相同的任务。在该任务中,它必须通过服务重新进行身份验证才能获取新的 session key 。但发生的情况是所有线程都尝试重新进行身份验证。

我想让第一个线程重新验证通过,其他线程等待完成,然后照常继续。

这是我在实现解决方案之前的原始测试代码:

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.

最佳答案

这是一个可能的解决方案:

            Thread thr = new Thread(() -> {
int count = 0;

while(count < 2) { // Bad practice but just for the example.
if (count == 1 && authClass.reAuthenticate()) {
System.out.println("Reauthenticated.");

authClass.doStuff();
} else {
authClass.doStuff();
}

count++;
}
});

在第一个代码片段中,我稍微修改了调用 auth.doStuff() 的逻辑,以防 reAuthenticate 返回 false

    private class AuthManager {

private volatile boolean reAuthenticate;
public boolean reAuthenticate(){
if (!reAuthenticate) {
synchronized (this) {
if (!reAuthenticate) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}

System.out.println("Reauthenticating..");

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignored
}
return this.reAuthenticate = true;
}
}
}
return false;
}

在第二个代码片段中,我依靠一个 volatile 变量来对值reAuthenticate进行双重检查,以便仅调用它一次,而不必为以后获取任何锁调用重新验证

关于java - 多线程方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36435591/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com