简体   繁体   English

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

[英]How to make sure the main thread continues only after child thread has started?

I am trying to write a program that first ssh'es to two different machines, and then executes some http requests against them. 我正在尝试编写一个程序,该程序首先将ssh加载到两台不同的计算机上,然后对它们执行一些http请求。 This means that in order to be able to execute my http requests the ssh tunnel should be running. 这意味着为了能够执行我的http请求,ssh隧道应该正在运行。

What I have done is that I have two threads, each running the ssh command to one of the boxes: 我所做的是,我有两个线程,每个线程都对其中一个框运行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();

Now the problem is that after starting the threads, they do not always immediately start running, which means that I will send my requests before the connection is made. 现在的问题是,启动线程后,它们并不总是立即开始运行,这意味着我将在建立连接之前发送请求。 Is there a simple way (without using locks or mutex) that I can make sure I only return to my main program after the threads are started? 是否有一种简单的方法(不使用锁或互斥锁)可以确保仅在线程启动后才返回主程序? (I don't want of course to wait for them to end because they never end. Just run the first command once :) Also if there is a better way to run the processes in the background instead of having these two seperate threads, that would be great too!) (我当然不想等待它们结束,因为它们永远不会结束。只需运行第一个命令一次即可:)另外,如果有更好的方法在后台运行进程,而不是使用这两个单独的线程,那太好了!)

Thanks! 谢谢!

Try adding the -f and -N flags to tell ssh to background itself once the port forwarding is setup. 设置端口转发后,尝试添加-f-N标志以使ssh自身进入后台。 Then you can execute the ssh commands in the main thread and wait until they exit (ie background themselves) before continuing. 然后,您可以在主线程中执行ssh命令,并等待它们退出(即,自身退出),然后再继续。

-f

Requests ssh to go to background just before command execution. 请求ssh在执行命令之前进入后台。 This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background. 如果ssh要求输入密码或口令,但用户希望在后台输入密码或口令,则此功能很有用。 This implies -n . 这意味着-n The recommended way to start X11 programs at a remote site is with something like ssh -f host xterm . 建议在远程站点上启动X11程序的方法是使用ssh -f host xterm

If the ExitOnForwardFailure configuration option is set to “yes”, then a client started with -f will wait for all remote port forwards to be successfully established before placing itself in the background. 如果ExitOnForwardFailure配置选项设置为“ yes”,则以-f开头的客户端将等待所有远程端口转发成功建立,然后再将其置于后台。

-N

Do not execute a remote command. 不要执行远程命令。 This is useful for just forwarding ports (protocol version 2 only). 这对于仅转发端口(仅协议版本2)很有用。

(Unfortunately I'm unable to test this at the moment. Apologies if it doesn't work.) (不幸的是,目前我无法对此进行测试。如果无法正常使用,我深表歉意。)

First of all using threads directly is not encouraged in JDK5 onwards. 首先,从JDK5开始不建议直接使用线程。 The well packed Executors will do the job for us. 打包的执行者将为我们完成这项工作。 If you have a lower version of java or you want to do this still in this way then, here is one quick solution, 如果您的Java版本较低,或者您仍希望以这种方式进行操作,那么这里有一个快速解决方案,

public class Main { 公共班级主要{

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();
        }
    }
}

} }

Regards Lyju 问候Lyju

You can use thread1.getState() method to get the state of the thread. 您可以使用thread1.getState()方法获取线程的状态。 After you can thread1.start() it should be moved to RUNNABLE state. 在可以使用thread1.start()之后,应将其移至RUNNABLE状态。 When thread1 is waiting for the process to finish it will be in BLOCKED state. 当thread1等待进程完成时,它将处于BLOCKED状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何确保仅启动一个线程 - How do I make sure only one thread gets started 通过主线程中的单独方法更改条件后,单独线程中的循环继续运行 - while loop in seperate thread continues running after condition has been changed via seperate method in main thread 确保只有 1 个线程在 Java 中运行 - Make sure only 1 thread running in Java 不确定如何在主线程中引用stringArray - Not sure how to reference stringArray in main thread 如何杀死子线程启动的进程? - How to kill a process which is started by child thread? 如何确保线程完成其任务,然后只有新线程才能在Java中启动? - How can I make sure a thread is completed its task,then only new Thread can start in java? 我们如何使用notifyAll来确保唤醒后仅继续一个线程? - How can we use notifyAll to ensure that only one thread continues after wakeup? 如何确定我的android runnable在辅助线程上启动? - How can I be sure that my android runnable started on a worker thread? 如何让程序等到计时器线程完成后再继续? - How to make the program wait until a timer thread is finished before it continues? 多线程-仅在启动所有线程之后,才让线程开始执行run() - Multithreading - Make thread start executing run() only after all threads have been started
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM