Java 多线程的并行执行和终止
我有一个简单的应用程序,我在一个类中创建了3个线程来ping 3个不同的网站,并记录了这样做所花费的时间 我希望通过查看3个线程中的哪个线程首先成功执行并终止其他两个线程来增强它 JDK的哪个类在这样做时会有帮助?怎么做 ping网站的示例代码:Java 多线程的并行执行和终止,java,multithreading,concurrency,parallel-processing,Java,Multithreading,Concurrency,Parallel Processing,我有一个简单的应用程序,我在一个类中创建了3个线程来ping 3个不同的网站,并记录了这样做所花费的时间 我希望通过查看3个线程中的哪个线程首先成功执行并终止其他两个线程来增强它 JDK的哪个类在这样做时会有帮助?怎么做 ping网站的示例代码: public static boolean pingUrl(final String address) { try { final URL url = new URL("http://" + address); final HttpUR
public static boolean pingUrl(final String address) {
try {
final URL url = new URL("http://" + address);
final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
urlConn.setConnectTimeout(1000 * 10); // mTimeout is in seconds
final long startTime = System.currentTimeMillis();
urlConn.connect();
final long endTime = System.currentTimeMillis();
if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("Time (ms) : " + (endTime - startTime));
System.out.println("Ping to "+address +" was success");
return true;
}
} catch (final MalformedURLException e1) {
e1.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
return false;
}
我想可能有用。主要思想是,生成的线程在完成时将一些值写入BlockingQueue
,并在InterruptedException
例如:
public void runPing(List<String> urls) {
Collection<Thread> runningThreads = new ArrayList<>(urls.size());
final BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(urls.size());
for (int i = 0; i < 3; i++) {
final String url = urls.get(i);
Thread t = new Thread(new Runnable() {
public void run() {
pingUrl(url);
queue.add(1);
}
});
runningThreads.add(t);
}
try {
queue.poll(1, TimeUnit.HOURS);
interruptChilds(runningThreads);
} catch (Exception e) {
interruptChilds(runningThreads);
}
}
private void interruptChilds(Collection<Thread> runningThreads) {
for (Thread t : runningThreads) {
t.interrupt();
}
}
公共无效运行(列出URL){
集合runningThreads=newarraylist(url.size());
final BlockingQueue=new ArrayBlockingQueue(url.size());
对于(int i=0;i<3;i++){
最终字符串url=url.get(i);
线程t=新线程(新的可运行线程(){
公开募捐{
pingUrl(url);
添加(1);
}
});
运行线程。添加(t);
}
试一试{
队列.轮询(1,时间单位.小时);
中断子线程(运行线程);
}捕获(例外e){
中断子线程(运行线程);
}
}
私有void interruptChilds(集合运行线程){
对于(线程t:运行线程){
t、 中断();
}
}
请注意,在中没有处理中断异常
。应该在您的方法中添加它我想可能有用。主要思想是,生成的线程在完成时将一些值写入BlockingQueue
,并在InterruptedException
例如:
public void runPing(List<String> urls) {
Collection<Thread> runningThreads = new ArrayList<>(urls.size());
final BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(urls.size());
for (int i = 0; i < 3; i++) {
final String url = urls.get(i);
Thread t = new Thread(new Runnable() {
public void run() {
pingUrl(url);
queue.add(1);
}
});
runningThreads.add(t);
}
try {
queue.poll(1, TimeUnit.HOURS);
interruptChilds(runningThreads);
} catch (Exception e) {
interruptChilds(runningThreads);
}
}
private void interruptChilds(Collection<Thread> runningThreads) {
for (Thread t : runningThreads) {
t.interrupt();
}
}
公共无效运行(列出URL){
集合runningThreads=newarraylist(url.size());
final BlockingQueue=new ArrayBlockingQueue(url.size());
对于(int i=0;i<3;i++){
最终字符串url=url.get(i);
线程t=新线程(新的可运行线程(){
公开募捐{
pingUrl(url);
添加(1);
}
});
运行线程。添加(t);
}
试一试{
队列.轮询(1,时间单位.小时);
中断子线程(运行线程);
}捕获(例外e){
中断子线程(运行线程);
}
}
私有void interruptChilds(集合运行线程){
对于(线程t:运行线程){
t、 中断();
}
}
请注意,在中没有处理中断异常
。应该将其添加到您的方法中
我希望通过查看3个线程中的哪个线程首先成功执行并终止其他两个线程来增强它
我将使用ExecutorService
与ExecutorCompletionService
组合使用。然后,当第一个任务完成时,从完成服务返回第一个Future
时,您可以在ExecutorService
上调用shutdownow()
这些工具非常好,并展示了如何使用它
// maybe you want 10 threads working on your tasks
ExecutorService threadPool = Executors.newFixedThreadPool(10);
CompletionService<Result> ecs
= new ExecutorCompletionService<Result>(threadPool);
for (Callable<Result> task : tasks) {
// submit your tasks to the completion service, they run in the thread-pool
ecs.submit(task);
}
// once you get one result
Future<Result> future = ecs.take();
// kill the rest of the tasks
threadPool.shutdownNow();
Result result = future.get();
// probably will need to close the thread connections, see below
// maybe call threadPool.awaitShutdown(...) here to wait for the others to die
在您的情况下,您的任务可能类似于:
public class MyPingTask implements Callable<Boolean> {
private String address;
public MyPingTask(String address) {
this.address = address;
}
public Boolean call() throws Exception {
// obviously the pingUrl code could go right here
return pingUrl(address);
}
}
公共类MyPingTask实现可调用{
私有字符串地址;
公共MyPingTask(字符串地址){
this.address=地址;
}
公共布尔调用()引发异常{
//显然pingUrl代码可能就在这里
返回pingUrl(地址);
}
}
下面是相关的课程
我希望通过查看3个线程中的哪个线程首先成功执行并终止其他两个线程来增强它
我将使用ExecutorService
与ExecutorCompletionService
组合使用。然后,当第一个任务完成时,从完成服务返回第一个Future
时,您可以在ExecutorService
上调用shutdownow()
这些工具非常好,并展示了如何使用它
// maybe you want 10 threads working on your tasks
ExecutorService threadPool = Executors.newFixedThreadPool(10);
CompletionService<Result> ecs
= new ExecutorCompletionService<Result>(threadPool);
for (Callable<Result> task : tasks) {
// submit your tasks to the completion service, they run in the thread-pool
ecs.submit(task);
}
// once you get one result
Future<Result> future = ecs.take();
// kill the rest of the tasks
threadPool.shutdownNow();
Result result = future.get();
// probably will need to close the thread connections, see below
// maybe call threadPool.awaitShutdown(...) here to wait for the others to die
在您的情况下,您的任务可能类似于:
public class MyPingTask implements Callable<Boolean> {
private String address;
public MyPingTask(String address) {
this.address = address;
}
public Boolean call() throws Exception {
// obviously the pingUrl code could go right here
return pingUrl(address);
}
}
公共类MyPingTask实现可调用{
私有字符串地址;
公共MyPingTask(字符串地址){
this.address=地址;
}
公共布尔调用()引发异常{
//显然pingUrl代码可能就在这里
返回pingUrl(地址);
}
}
这是和相关的类。你是如何ping网站的?@vandale添加了示例代码为了正确终止线程,你必须中止urlConn.connect()
,我认为这是不可能的。你是如何ping网站的?@vandale添加了示例代码为了正确终止线程,您必须中止urlConn.connect()
,我认为这是不可能的答案!中断问题的可能解决方法:使用自定义ThreadPoolExecutor
和重写方法newTaskFor(可调用)
代替newFixedThreadPool(…)
。它返回一个自定义的RunnableFuture
,该自定义RunnableFuture
知道可调用的拥有一个HttpURLConnection
(或HttpClient
请求对象),并在其cancel
方法中关闭其连接/中止其请求。从未这样做过@isnot2bad,但听起来它会工作。当然不适合初级线程程序员。回答不错!中断问题的可能解决方法:使用自定义ThreadPoolExecutor
和重写方法newTaskFor(可调用)
代替newFixedThreadPool(…)
。它返回一个自定义的RunnableFuture
,该自定义RunnableFuture
知道可调用的拥有一个HttpURLConnection
(或HttpClient
请求对象),并在其cancel
方法中关闭其连接/中止其请求。从未这样做过@isnot2bad,但听起来它会工作。当然,对于初级线程程序员来说肯定不是。