Java 如何确保主线程仅在子线程启动后继续?

Java 如何确保主线程仅在子线程启动后继续?,java,multithreading,ssh,Java,Multithreading,Ssh,我正在尝试编写一个程序,该程序首先将ssh’s连接到两台不同的机器,然后对它们执行一些http请求。这意味着为了能够执行我的http请求,应该运行ssh隧道 我所做的是,我有两个线程,每个线程运行ssh命令到其中一个框: Thread thread1 = new Thread(new Runnable(){ public void run(){ try{ Process p1 = Runtim

我正在尝试编写一个程序,该程序首先将ssh’s连接到两台不同的机器,然后对它们执行一些http请求。这意味着为了能够执行我的http请求,应该运行ssh隧道

我所做的是,我有两个线程,每个线程运行ssh命令到其中一个框:

    Thread thread1 = new Thread(new Runnable(){
            public void run(){
                try{
                    Process p1 = Runtime.getRuntime().exec("ssh -A -L12345:localhost:54321 firsthost.com");
                    p1.waitFor();
                }catch (Exception e){}
            }
        }) ;
        thread1.start();

    Thread thread2 = new Thread(new Runnable(){
        public void run(){
            try{
                Process p2 = Runtime.getRuntime().exec("ssh -A -L12345:localhost:54321 secondhost.com");
                p2.waitFor();
            }catch (Exception e){}
        }
    }) ;
    thread2.start();
现在的问题是,在启动线程之后,它们并不总是立即开始运行,这意味着我将在建立连接之前发送请求。有没有一种简单的方法(不使用锁或互斥)可以确保我只在线程启动后返回主程序?(我当然不想等待它们结束,因为它们永远不会结束。只需运行第一个命令一次:)如果有更好的方法在后台运行进程,而不是使用这两个单独的线程,那也太好了!)


谢谢

可以使用thread1.getState()方法获取线程的状态。完成thread1.start()后,应将其移动到可运行状态。当thread1等待进程完成时,它将处于阻塞状态。

尝试添加
-f
-N
标志,以便在设置端口转发后通知ssh到后台。然后,您可以在主线程中执行
ssh
命令,并等待它们退出(即后台本身),然后继续

-f

在命令执行之前请求ssh转到后台。如果ssh要请求密码或密码短语,但用户希望在后台使用,那么这非常有用。这意味着
-n
。在远程站点启动X11程序的推荐方法是使用类似于
ssh-f host xterm
的东西

如果ExitOnForwardFailure配置选项设置为“是”,则使用
-f
启动的客户端将等待所有远程端口转发成功建立,然后将其置于后台

-N

不要执行远程命令。这仅适用于转发端口(仅限协议版本2)


(不幸的是,我目前无法对此进行测试。如果它不起作用,我深表歉意。)

首先,JDK5以后不鼓励直接使用线程。那些人满为患的遗嘱执行人将为我们做这项工作。如果您有一个较低版本的java,或者您仍然希望这样做,那么这里有一个快速解决方案

公共班机{

public static void main(String... objs) throws Exception {

    final Process1Thread p1Thread = new Process1Thread();
    final Process2Thread p2Thread = new Process2Thread();

     Thread p1 = new Thread(p1Thread);
     Thread p2 = new Thread(p2Thread);

     p1.start(); p2.start();

     while(true) {
         if(p1Thread.isFinishedCommand() && p2Thread.isFinishedCommand()) {
             //send commands
            System.out.println("sending commands"); 
             break;
         }   
     }       
}

interface FinishedCommand {
    boolean isFinishedCommand();
}

static class Process1Thread implements Runnable, FinishedCommand {

    private boolean finished = false; 

    @Override
    public boolean isFinishedCommand() {
        synchronized(this) {
            return finished;
        }
    }

    @Override
    public void run() {         
        try {
            final Process p2 = Runtime.getRuntime().exec("dir");

            synchronized(this) {
                finished = true;
            }               
            p2.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }       
}


static class Process2Thread implements Runnable, FinishedCommand {

    private boolean finished = false; 

    @Override
    public boolean isFinishedCommand() {
        synchronized(this) {
            return finished;
        }
    }

    @Override
    public void run() {         
        try {
            final Process p2 = Runtime.getRuntime().exec("dir");

            synchronized(this) {
                finished = true;
            }               
            p2.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
}

问候
Lyju

这无助于了解
ssh
何时成功设置端口转发。非常感谢!是的,有了-f和-N,它就成功了。我现在只需要弄清楚如何避免输入我的密码。(当我从shell执行ssh时,它不会以某种方式提示输入我的密码短语,但它是这样做的。)但除此之外,这是一个非常简单的解决方案:)