Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Spring线程和TaskExecutor,我如何知道线程何时完成?_Java_Spring_Multithreading - Fatal编程技术网

Java 使用Spring线程和TaskExecutor,我如何知道线程何时完成?

Java 使用Spring线程和TaskExecutor,我如何知道线程何时完成?,java,spring,multithreading,Java,Spring,Multithreading,好吧,这里可能有个天真的问题。我有一个服务需要登录到多个网络设备,在每个设备上运行命令并收集结果。为了提高速度,我需要同时访问所有设备,而不是按顺序收集每个设备上的信息,并在完成后使用结果 使用Spring框架和Jsch,我可以很容易地正确查询每个设备。我遇到一些困惑的地方是尝试重新连接bean以使用TaskExecutor来完成这项任务。我不知道怎么做的是如何知道线程何时完成 到目前为止,我得到的是: public class RemoteCommand { private Stri

好吧,这里可能有个天真的问题。我有一个服务需要登录到多个网络设备,在每个设备上运行命令并收集结果。为了提高速度,我需要同时访问所有设备,而不是按顺序收集每个设备上的信息,并在完成后使用结果

使用Spring框架和Jsch,我可以很容易地正确查询每个设备。我遇到一些困惑的地方是尝试重新连接bean以使用TaskExecutor来完成这项任务。我不知道怎么做的是如何知道线程何时完成

到目前为止,我得到的是:

public class RemoteCommand {

    private String user;
    private String host;
    private String password;
    private String command;
    private List<String> commandResults;
    private TaskExecutor taskExecutor;

    public RemoteCommand(String user, String host, String password, TaskExecutor taskExecutor) {

        setUser(user);
        setHost(host);
        setPassword(password);
        setTaskExecutor(taskExecutor);
    }

    /**
     * @param user the user to set
     */
    public void setUser(String user) {
        this.user = user;
    }

    /**
     * @return the user
     */
    public String getUser() {
        return user;
    }

    /**
     * @param host the host to set
     */
    public void setHost(String host) {
        this.host = host;
    }

    /**
     * @return the host
     */
    public String getHost() {
        return host;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param command the command to set
     */
    private void setCommand(String command) {
        this.command = command;
    }

    /**
     * @return the command
     */
    private String getCommand() {
        return command;
    }

    /**
     * @param commandResults the commandResults to set
     */
    private void setCommandResults(List<String> commandResults) {
        this.commandResults = commandResults;
    }

    /**
     * @return the commandResults
     */
    public List<String> getCommandResults(String command) {
        taskExecutor.execute(new CommandTask(command) );

        return commandResults;
    }

    /**
     * @param taskExecutor the taskExecutor to set
     */
    public void setTaskExecutor(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }

    /**
     * @return the taskExecutor
     */
    public TaskExecutor getTaskExecutor() {
        return taskExecutor;
    }

    private class CommandTask implements Runnable {

        public CommandTask(String command) {
            setCommand(command);
            System.out.println("test: " + getCommand());
        }

        /**
         * 
         * @param command
         */
        public void run() {

            List<String> results = new LinkedList<String>();
            String command = getCommand();

            try {
                System.out.println("running");
                JSch jsch = new JSch();

                String user = getUser();
                String host = getHost();

                java.util.Properties config = new java.util.Properties(); 
                config.put("StrictHostKeyChecking", "no");

                host = host.substring(host.indexOf('@') + 1);
                Session session = jsch.getSession(user, host, 22);

                session.setPassword(getPassword());
                session.setConfig(config);
                session.connect();

                Channel channel = session.openChannel("exec");
                ((ChannelExec) channel).setCommand(command);

                channel.setInputStream(null);

                ((ChannelExec) channel).setErrStream(System.err);

                InputStream in = channel.getInputStream();

                channel.connect();
                byte[] tmp = new byte[1024];
                while (true) {
                    while (in.available() > 0) {
                        int i = in.read(tmp, 0, 1024);
                        if (i < 0)
                            break;
                        results.add(new String(tmp, 0, i));
                        System.out.print(new String(tmp, 0, i));
                    }
                    if (channel.isClosed()) {
                        //System.out.println("exit-status: "
                        //      + channel.getExitStatus());
                        break;
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (Exception ee) {
                        ee.printStackTrace();
                    }
                }
                channel.disconnect();
                session.disconnect();
            } catch (Exception e) {
                System.out.println(e);
            }
            setCommandResults(results);
            System.out.println("finished running");
        }
    }
}
公共类RemoteCommand{
私有字符串用户;
私有字符串主机;
私有字符串密码;
私有字符串命令;
私有列表结果;
私有任务执行器任务执行器;
公共远程命令(字符串用户、字符串主机、字符串密码、TaskExecutor TaskExecutor){
setUser(用户);
setHost(主机);
设置密码(密码);
setTaskExecutor(taskExecutor);
}
/**
*@param user要设置的用户
*/
公共void setUser(字符串用户){
this.user=用户;
}
/**
*@返回用户
*/
公共字符串getUser(){
返回用户;
}
/**
*@param host要设置的主机
*/
公共void setHost(字符串主机){
this.host=host;
}
/**
*@返回主机
*/
公共字符串getHost(){
返回主机;
}
/**
*@param password要设置的密码
*/
public void setPassword(字符串密码){
this.password=密码;
}
/**
*@返回密码
*/
公共字符串getPassword(){
返回密码;
}
/**
*@param命令要设置的命令
*/
私有void setCommand(字符串命令){
this.command=命令;
}
/**
*@返回命令
*/
私有字符串getCommand(){
返回命令;
}
/**
*@param commandResults要设置的commandResults
*/
私有void setCommandResults(列出commandResults){
this.commandResults=commandResults;
}
/**
*@返回命令结果
*/
公共列表getCommandResults(字符串命令){
taskExecutor.execute(新命令任务(命令));
返回结果;
}
/**
*@param taskExecutor要设置的taskExecutor
*/
public void setTaskExecutor(TaskExecutor TaskExecutor){
this.taskExecutor=taskExecutor;
}
/**
*@返回任务执行器
*/
公共任务执行器getTaskExecutor(){
返回任务执行器;
}
私有类CommandTask实现可运行{
公共命令任务(字符串命令){
setCommand(命令);
System.out.println(“测试:+getCommand());
}
/**
* 
*@param命令
*/
公开募捐{
列表结果=新建LinkedList();
String command=getCommand();
试一试{
System.out.println(“运行”);
JSch JSch=新的JSch();
字符串user=getUser();
字符串host=getHost();
java.util.Properties config=new java.util.Properties();
配置放置(“检查”、“否”);
host=host.substring(host.indexOf('@')+1);
Session Session=jsch.getSession(用户,主机,22);
setPassword(getPassword());
session.setConfig(config);
session.connect();
Channel=session.openChannel(“exec”);
((ChannelExec)channel).setCommand(command);
channel.setInputStream(空);
((ChannelExec)channel.setErrStream(System.err);
InputStream in=channel.getInputStream();
channel.connect();
字节[]tmp=新字节[1024];
while(true){
while(in.available()>0){
inti=in.read(tmp,0,1024);
if(i<0)
打破
添加(新字符串(tmp,0,i));
系统输出打印(新字符串(tmp,0,i));
}
if(channel.isClosed()){
//System.out.println(“退出状态:”
//+channel.getExitStatus());
打破
}
试一试{
睡眠(1000);
}捕获(异常ee){
ee.printStackTrace();
}
}
通道断开();
session.disconnect();
}捕获(例外e){
系统输出打印ln(e);
}
setCommandResults(结果);
System.out.println(“已完成运行”);
}
}
}
在junit测试中,我有:

@Test
    public void testRemoteExecution() {

        remoteCommand = (RemoteCommand) applicationContext.getBean("remoteCommand");
        remoteCommand.getCommandResults("scripts/something.pl xxx.xxx.xxx.xxx");

            //List<String> results = remoteCommand.getCommandResults("scripts/something.pl xxx.xxx.xxx.xxx");
        //for (String line : results) {
        //  System.out.println(line.trim());
        //}
    }
@测试
public void testRemoteExecution(){
remoteCommand=(remoteCommand)applicationContext.getBean(“remoteCommand”);
getCommandResults(“scripts/something.pl xxx.xxx.xxx.xxx”);
//List results=remoteCommand.getCommandResults(“scripts/something.pl xxx.xxx.xxx.xxx”);
//用于(字符串行:结果){
//System.out.println(line.trim());
//}
}
My applicationContext.xml文件:

    <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
       <property name="corePoolSize" value="5" />
       <property name="maxPoolSize" value="10" />
       <property name="queueCapacity" value="25" />
    </bean>        

<!-- ******************** -->
<!--      Utilities       -->
<!-- ******************** -->

     <bean name="remoteCommand" class="com.xxx.ncc.sonet.utilities.RemoteCommand" scope="prototype">
        <description>Remote Command</description>
        <constructor-arg><value>${remote.user}</value></constructor-arg>
        <constructor-arg><value>${remote.host}</value></constructor-arg>
        <constructor-arg><value>${remote.password}</value></constructor-arg>
        <constructor-arg ref="taskExecutor" />
    </bean> 

远程命令
${remote.user}
${remote.host}
${remote.password}
我得到run()方法中的第一个println。然后测试将干净地退出,没有错误。我从来没有到过t底部的第二个println
public List<String> getCommandResults(String command) {
   Future<List<String>> futureResults = taskExecutor.submit(new CommandTask(command));
   return futureResults.get();
}
public List<String> getCommandResults(String command) {
    FutureTask task = new FutureTask(new CommandTask(command))
    taskExecutor.execute(task);

    return task.get(); //or task.get(); return commandResults; - but it not a good practice
}