Java 带列表的循环迭代的线程实现

Java 带列表的循环迭代的线程实现,java,multithreading,list,arraylist,thread-safety,Java,Multithreading,List,Arraylist,Thread Safety,我有一个简单的代码如下。这将检查服务器列表的活动状态。 您能告诉我如何使用线程或任何其他合适的解决方案并行完成这项工作吗 List<Host> hosts = this.getAllHosts(); List<Host> aliveHosts = new ArrayList<>(); if (hosts != null && hosts.size() > 0) { f

我有一个简单的代码如下。这将检查服务器列表的活动状态。 您能告诉我如何使用线程或任何其他合适的解决方案并行完成这项工作吗

        List<Host> hosts = this.getAllHosts();
        List<Host> aliveHosts = new ArrayList<>();
        if (hosts != null && hosts.size() > 0) {
            for (Host host : hosts) {
                try {
                    if(InetAddress.getByName(host.getIpaddress()).isReachable(TIMEOUT)) {
                        aliveHosts.add(host);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return aliveHosts;
List hosts=this.getAllHosts();
List aliveHosts=new ArrayList();
if(hosts!=null&&hosts.size()>0){
用于(主机:主机){
试一试{
if(InetAddress.getByName(host.getIpaddress()).isRecable(超时)){
aliveHosts.add(主机);
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
返回aliveHosts;
如何在线程中调用每个
getByName
,并同时并行执行。目前,他们每个人都有3秒的超时时间。如果有10项,则总时间为30秒。任何人都可以给出一个解决方案,这样就可以在3-8秒内全部完成。

使用Java 8流:

List<Host> aliveHosts = hosts.stream()
                             .parallel()
                             .filter(h -> {
                                            try {
                                              return InetAddress.getByName(h.getIpaddress()).isReachable(TIMEOUT)
                                            } catch(Exception e) {
                                              return false;
                                            }
                                          })
                             .collect(Collectors.toList());
List aliveHosts=hosts.stream()
.parallel()
.过滤器(h->{
试一试{
返回InetAddress.getByName(h.getIpaddress()).IsRecable(超时)
}捕获(例外e){
返回false;
}
})
.collect(Collectors.toList());

<代码> > p>让我们考虑这个线程例子:

public class SimpleThreads {

    // Display a message, preceded by
    // the name of the current thread
    static void threadMessage(String message) {
        String threadName =
            Thread.currentThread().getName();
        System.out.format("%s: %s%n",
                          threadName,
                          message);
    }

    private static class MessageLoop
        implements Runnable {
        public void run() {
            String importantInfo[] = {
                "Mares eat oats",
                "Does eat oats",
                "Little lambs eat ivy",
                "A kid will eat ivy too"
            };
            try {
                for (int i = 0;
                     i < importantInfo.length;
                     i++) {
                    // Pause for 4 seconds
                    Thread.sleep(4000);
                    // Print a message
                    threadMessage(importantInfo[i]);
                }
            } catch (InterruptedException e) {
                threadMessage("I wasn't done!");
            }
        }
    }

    public static void main(String args[])
        throws InterruptedException {

        // Delay, in milliseconds before
        // we interrupt MessageLoop
        // thread (default one hour).
        long patience = 1000 * 60 * 60;

        // If command line argument
        // present, gives patience
        // in seconds.
        if (args.length > 0) {
            try {
                patience = Long.parseLong(args[0]) * 1000;
            } catch (NumberFormatException e) {
                System.err.println("Argument must be an integer.");
                System.exit(1);
            }
        }

        threadMessage("Starting MessageLoop thread");
        long startTime = System.currentTimeMillis();
        Thread t = new Thread(new MessageLoop());
        t.start();

        threadMessage("Waiting for MessageLoop thread to finish");
        // loop until MessageLoop
        // thread exits
        while (t.isAlive()) {
            threadMessage("Still waiting...");
            // Wait maximum of 1 second
            // for MessageLoop thread
            // to finish.
            t.join(1000);
            if (((System.currentTimeMillis() - startTime) > patience)
                  && t.isAlive()) {
                threadMessage("Tired of waiting!");
                t.interrupt();
                // Shouldn't be long now
                // -- wait indefinitely
                t.join();
            }
        }
        threadMessage("Finally!");
    }
}
公共类SimpleThreads{
//显示一条消息,前面有
//当前线程的名称
静态无效线程消息(字符串消息){
字符串线程名=
Thread.currentThread().getName();
System.out.format(“%s:%s%n”,
threadName,
信息);
}
私有静态类MessageLoop
实现可运行{
公开募捐{
字符串重要性信息[]={
“母马吃燕麦”,
“他吃燕麦吗”,
“小羊羔吃常春藤”,
“孩子也会吃常春藤”
};
试一试{
对于(int i=0;
i<重要信息长度;
(i++){
//暂停4秒钟
睡眠(4000);
//打印消息
threadMessage(重要信息[i]);
}
}捕捉(中断异常e){
threadMessage(“我还没做完!”);
}
}
}
公共静态void main(字符串参数[])
抛出中断异常{
//延迟,以毫秒为单位
//我们中断信息循环
//线程(默认为一小时)。
长期耐心=1000*60*60;
//If命令行参数
//现在,给予耐心
//几秒钟之内。
如果(args.length>0){
试一试{
耐心=Long.parseLong(args[0])*1000;
}捕获(数字格式){
System.err.println(“参数必须是整数。”);
系统出口(1);
}
}
threadMessage(“启动MessageLoop线程”);
long startTime=System.currentTimeMillis();
线程t=新线程(newmessageloop());
t、 start();
threadMessage(“等待MessageLoop线程完成”);
//循环直到消息循环
//线程出口
while(t.isAlive()){
threadMessage(“仍在等待…”);
//最多等待1秒
//对于MessageLoop线程
//结束。
t、 加入(1000);
if(((System.currentTimeMillis()-startTime)>耐心)
&&t.isAlive()){
threadMessage(“厌倦了等待!”);
t、 中断();
//现在应该不会太久了
//--无限期地等待
t、 join();
}
}
threadMessage(“终于!”);
}
}


本质上,您需要一个
Runnable
,它负责线程的工作方式。您需要实例化一个线程,传递您拥有的
Runnable
的实例,然后
start
您的
线程。您需要让所有线程都可以访问,并将它们删除。您可以。

非Java 8方式看起来类似:

List<Host> hosts = this.getAllHosts();

    Queue<Host> q = new ArrayBlockingQueue<>(hosts.size(), true, hosts);
    ExecutorService ex = Executors.newFixedThreadPool(5);
    List<Host> aliveHosts = Collections.synchronizedList(new ArrayList<>());

    while(!q.isEmpty()){
        ex.submit(new Runnable() {
            @Override
            public void run() {
                Host host = q.poll();
                try {
                    if(InetAddress.getByName(host.getIpaddress()).isReachable(TIMEOUT)) {
                        aliveHosts.add(host);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
    }
    ex.shutdown();
}
List hosts=this.getAllHosts();
队列q=新的ArrayBlockingQueue(hosts.size(),true,hosts);
ExecutorService ex=Executors.newFixedThreadPool(5);
List aliveHosts=Collections.synchronizedList(新的ArrayList());
而(!q.isEmpty()){
ex.submit(新的可运行(){
@凌驾
公开募捐{
主机=q.poll();
试一试{
if(InetAddress.getByName(host.getIpaddress()).isRecable(超时)){
aliveHosts.add(主机);
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
});
}
例如关闭();
}

Java8和
ExecutorService

List<Host> hosts = this.getAllHosts();
List<Host> aliveHosts = Collections.synchronizedList(new ArrayList<Host>());
ExecutorService executorService = Executors.newFixedThreadPool(10);
if (hosts != null && hosts.size() > 0) {
    for (Host host : hosts) {
        executorService.submit(() -> {
            try {
                if (InetAddress.getByName(host.getIpaddress()).isReachable(TIMEOUT)) {
                    aliveHosts.add(host);
                }
            } catch (IOException e) {
                // logger?
            }
        });
    }
}
executorService.shutdown();
return aliveHosts;
List hosts=this.getAllHosts();
List aliveHosts=Collections.synchronizedList(新的ArrayList());
ExecutorService ExecutorService=Executors.newFixedThreadPool(10);
if(hosts!=null&&hosts.size()>0){
用于(主机:主机){
executorService.submit(()->{
试一试{
if(InetAddress.getByName(host.getIpaddress()).isRecable(超时)){
aliveHosts.add(主机);
}
}捕获(IOE异常){
//记录器?
}
});
}
final Predicate<Host> isAlive = h -> {
    try {
        return InetAddress.getByName(h.getIpaddress()).isReachable(TIMEOUT);
    } catch (Exception e) {
        return false;
    }
};
final Callable<List<Host>> collectAliveHosts = () ->
    hosts.stream().parallel().filter(isAlive).collect(Collectors.toList());

final ForkJoinPool threadPool = new ForkJoinPool(4);
final List<Host> aliveHosts = threadPool.submit(collectAliveHosts).get();
package test.basics;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class TestFutureTask {
    private static final int TIMEOUT = 30000;

    public static void main(String[] args) {
        List<String> hosts = new ArrayList<String>();
        hosts.add("127.0.0.1");
        hosts.add("127.0.0.2");
        hosts.add("127.0.0.3");
        hosts.add("127.0.0.4");
        hosts.add("127.0.0.5");
        hosts.add("127.0.0.6");
        List<String> aliveHosts = new ArrayList<>();
        List<String> notAliveHosts = new ArrayList<>();

        long stTime = System.currentTimeMillis();
        System.out.println("Starting time " + stTime);
        Map<String, Future> jobList = new HashMap<>();
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        for (String host : hosts) {

            Future f = newCachedThreadPool.submit(new Callable<Boolean>() {

                private String host;

                @Override
                public Boolean call() throws Exception {
                    return InetAddress.getByName(host).isReachable(TIMEOUT);
                }

                public Callable<Boolean> init(String host) {
                    this.host = host;
                    return this;
                }
            }.init(host));

            jobList.put(host, f);

        }

        for (String host : jobList.keySet()) {
            try {
                if ((boolean) jobList.get(host).get()) {
                    aliveHosts.add(host);
                } else {
                    notAliveHosts.add(host);
                }
            } catch (InterruptedException | ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Ending time : " + endTime);
        System.out.println("Time taken :" + (endTime - stTime));
        System.out.println("Alive hosts: " + aliveHosts);
        System.out.println("Not alive hosts: " + notAliveHosts);
    }
}