gpt4 book ai didi

Java线程设计

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:32:38 26 4
gpt4 key购买 nike

我正在尝试做一个示例实用程序 java 代码,我需要使用线程来实现,但我不确定如果我所做的是最佳的。

这是我的用例:主线程会创建一个子线程。子线程将创建另外两个线程(WebCallThread 和 RestCallThread),它们将调用 REST 网络服务。

我在这里使用了线程,因为从 REST 调用中检索值需要一些时间。基本上 REST 服务只是返回 double 列表。

为了简单起见,我只是在这里使用 Math.random() 来生成代码...

package com.thread;
import java.util.ArrayList;
import java.util.List;


public class SampleThreads {
static List<Double> dblList = new ArrayList<Double>();
static List<Double> statelList = new ArrayList<Double>();

static boolean webResult = false;
static boolean restResult = false;

public static void main(String[] args) {
System.out.println("Starting ThreadTesting!!!!");
ChildThread childThread = new ChildThread();;
childThread.start();

try {
childThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


if(webResult && restResult) {
System.out.println("Success WebCall!!!!");
System.out.println(dblList);
System.out.println(statelList);
}else {
System.out.println("Something gone wrong!!!!!");
}

System.out.println("Finished ThreadTesting!!!!");
}

static class ChildThread extends Thread {

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Starting ChildThread!!!!");
WebCallThread webThread = new WebCallThread();
webThread.start();

RestCallThread restThread = new RestCallThread();
restThread.start();

try {
webThread.join();
restThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Finished ChildThread!!!!");
}

}

static class WebCallThread extends Thread {

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Starting WebCallThread!!!!");
int ctr =0;
while(true) {
if(ctr > 5) {
webResult = true;
System.out.println("Finished WebCallThread!!!!");
return;
}
System.out.println("Adding to WebCallThread :: " + ctr);
dblList.add(Math.random());
ctr++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}

static class RestCallThread extends Thread {

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Starting RestCallThread!!!!");
int ctr =0;
while(true) {
if(ctr > 10) {
restResult = true;
System.out.println("Finished RestCallThread!!!!");
return;
}
System.out.println("Adding to RestCallThread :: " + ctr);
statelList.add(Math.random());
ctr++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}
}

我有点担心我检查 webResult 和 restResult 在这里是否正常或线程安全..如果线程被中断或调用 REST 服务失败怎么办。所以可以假设这些值不会正确更新并且我可以记录“出了点问题!!!!”消息?

if(webResult && restResult) {
System.out.println("Success WebCall!!!!");
System.out.println(dblList);
System.out.println(statelList);
}else {
System.out.println("Something gone wrong!!!!!");
}

另外,我使用变量在我的主线程中保存返回的 REST 结果,我将对结果进行处理。此线程的值由我的 REST Web 服务调用填充。

static List<Double> dblList = new ArrayList<Double>();
static List<Double> statelList = new ArrayList<Double>();

我不是 Java 线程专家,我只是临时写的。有人可以挑剔我的代码,它是否有可能失败?我愿意接受有关更好代码的建议。

最佳答案

我可以指出您的实现中的几个问题。首先,使用 static boolean 变量,例如 webResultrestResult 是违反直觉的,而且容易出错。这些变量由多个线程读取和写入,并可能导致并发设置中的竞争条件。您可以使用像 CountDownLatch 这样的线程协调机制来更优雅地实现相同的目标。

另一点是,您的线程 WebCallThreadRestCallThread 都将结果添加到共享数据结构中,该结构由其他线程使用,例如主 Thread。这可能会导致另一个竞争条件。因此,您可以在此处使用 Callable 而不是 Runnable

最后为每个请求创建一个新线程并不是一个好的做法,因为创建线程的成本很高。因此,您可以使用 ExecutorService 并从池中共享几个线程,以克服与不必要的线程创建相关的成本。

最后,但并非最不重要的是,您可以摆脱 ChildThread 并将该简单逻辑放在主线程中。

下面给出了具有上述建议更改的改进代码。

public class SampleThreads {
private static final CountDownLatch latch = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException, ExecutionException {
System.out.println("Starting ThreadTesting!!!!");

ExecutorService executor = Executors.newFixedThreadPool(4);

try {
Future<List<Double>> webResponse = executor.submit(new WebCallThread());
Future<List<Double>> restResponse = executor.submit(new RestCallThread());
latch.await();
System.out.println("Success WebCall!!!!");
System.out.println(webResponse.get());
System.out.println(restResponse.get());
System.out.println("Finished ThreadTesting!!!!");
} finally {
executor.shutdown();
}
}

static class WebCallThread implements Callable<List<Double>> {
@Override
public List<Double> call() throws Exception {
final List<Double> dblList = new ArrayList<>();
System.out.println("Starting WebCallThread!!!!");
int ctr = 0;
while (true) {
if (ctr > 5) {
latch.countDown();
System.out.println("Finished WebCallThread!!!!");
return dblList;
}
System.out.println("Adding to WebCallThread :: " + ctr);
dblList.add(Math.random());
ctr++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

static class RestCallThread implements Callable<List<Double>> {
@Override
public List<Double> call() throws Exception {
List<Double> statelList = new ArrayList<>();
System.out.println("Starting RestCallThread!!!!");
int ctr = 0;
while (true) {
if (ctr > 10) {
latch.countDown();
System.out.println("Finished RestCallThread!!!!");
return statelList;
}
System.out.println("Adding to RestCallThread :: " + ctr);
statelList.add(Math.random());
ctr++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
}

关于Java线程设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50831187/

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