简体   繁体   English

当主线程继续时,执行两个线程,等待另一个线程

[英]Execute two threads which wait one for the other while main thread continues

How can I start two threads where thread1 executes first, thread2 starts when thread1 ends while the main method thread can continue its work without locking on the other two? 如何启动thread1首先执行的两个线程,thread2在thread1结束时启动,而main方法线程可以继续工作而不锁定另外两个?

I have tried join() however it needs to be called from the thread which has to wait for the other, there's no way to do something like thread2.join(thread1); 我已经尝试了join()但是它需要从线程调用,它必须等待另一个,没有办法像thread2.join(thread1)那样做; If I call for a join inside main() I therefore effectively stop execution of the main thread and not only of thread2. 如果我在main()中调用连接,那么我有效​​地停止执行主线程,而不仅仅是thread2。

I therefore tried with ExecutorService but again same problem. 因此,我尝试使用ExecutorService,但同样的问题。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Test
{
    public static void main(String args[]) throws InterruptedException
    {
        System.out.println(Thread.currentThread().getName() + " is Started");

        class TestThread extends Thread
        {
            String name;
            public TestThread(String name)
            {
                this.name = name;
            }

            @Override
            public void run()
            {
                try
                {
                    System.out.println(this + " is Started");
                    Thread.sleep(2000);
                    System.out.println(this + " is Completed");
                }
                catch (InterruptedException ex)  {  ex.printStackTrace(); }
            }

            @Override
            public String toString()  { return "Thread " + name; }
        }

        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new TestThread("1"));

        boolean finished = executor.awaitTermination(1, TimeUnit.HOURS);

        if(finished)
        {
           //I should execute thread 2 only after thread 1 has finished
            executor.execute(new TestThread("2"));
        }

        //I should arrive here while process 1 and 2 go on with their execution
        System.out.println("Hello");
    }
}

#EDIT: Why I need this: #EDIT:为什么我需要这个:

I need this because Thread1 copies elements from a database table into another database, thread2 has to copy a linking table which references the table copied from thread1. 我需要这个,因为Thread1将数据库表中的元素复制到另一个数据库中,thread2必须复制一个引用从thread1复制的表的链接表。 Consequently thread2 has to start populating its linking table only when thread1 has finished otherwise an integrity error is given by the database. 因此,thread2只有在thread1完成时才开始填充其链接表,否则数据库会给出完整性错误。 Now imagine I have several threads with different priorities due to complex linking tables and you have an idea. 现在想象一下,由于复杂的链接表,我有几个不同优先级的线程,你有一个想法。

The second Thread can be custom like this (takes as argument the previous thread): 第二个Thread可以像这样自定义(作为前一个线程的参数):

public static void main(String[] a) {
    Thread first = new Thread(new Runnable() {
        @Override
        public void run() {

        }
    });

    Thread second = new MyThread(first);
    first.start();
    second.start();

    //continue executing
}

public static class MyThread extends Thread {

    private Thread predecessor;

    public MyThread(Thread predecessor) {
        this.predecessor = predecessor;
    }

    public void run() {
        if (predecessor != null && predecessor.isAlive()) {
            try {
                predecessor.join();
            } catch (InterruptedException e) {}
        }
        //do your stuff
    }
}

I am pretty sure you got something wrong because this must work and it does work: 我很确定你有错误,因为这必须有效,它确实有效:

new Thread() {
    @Override
    public void run() {
        TestThread t1= new TestThread("1");
        TestThread t2= new TestThread("2");
        try {
            t1.start();
            t1.join();
            t2.start();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}.start();

The ouput is: 输出是:

main is Started
Hello
Thread 1 is Started
Thread 1 is Completed
Thread 2 is Started
Thread 2 is Completed

Another option would be to extend the TestThread for the "Thread 1" to execute the work of "Thread 2" after it has been done with its own work. 另一个选择是扩展“线程1”的TestThread,以便在完成自己的工作后执行“线程2”的工作。 Something similar to this: 与此类似的东西:

final TestThread t2= new TestThread("2");
TestThread t1= new TestThread("1") {
    @Override
    public void run() {
        super.run(); //finish t1 work
        t2.start();  // start t2 work
    }
};
t1.start();

You can use a CountDownLatch : 您可以使用CountDownLatch

create it in the main thread, pass it on to both threads and call countdown on it in thread one when it exits and await it being counted down at the start of thread 2. 在主线程中创建它,将它传递给两个线程,并在它退出时在线程1中调用倒计时,并等待它在线程2的开始倒计时。

Why not just have thread1 be the one to start thread2? 为什么不让thread1成为启动thread2的人?

// in main
new Thread(new Runnable() {
    @Override public void run() {
        // do thread1 work
        new Thread(new Runnable() {
              @Override public void run() { /* do thread2 work */ }
        }).start();
    }
}).start();

However, it's not at all clear why you would want to do this as opposed to just having thread1 do 100% of the background work. 但是,完全不清楚为什么要这样做而不是让thread1完成100%的后台工作。

You can use SingleThreadExecutor to run one task after another Java doc 您可以使用SingleThreadExecutor在另一个Java文档之后运行一个任务

So it will put your task one after another and they will execute in sequence without blocking main thread 所以它会一个接一个地执行你的任务,它们将按顺序执行而不会阻塞主线程

Try this, This will work as expected. 试试这个,这将按预期工作。 Two threads printing odd and even one after another and main exiting as soon as possible. 两个线程一个接一个地打印奇数和偶数,并且主要尽快退出。

public class YoThreD {

    static boolean isThread1 = false;

    public static synchronized boolean isThread1() {
        return isThread1 = !isThread1;
    }

    public static void main(String args[]) {

        Runnable runnableObject = new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    for (int i = 1; i <= 100; i++) {
                        try {
                            if (Thread.currentThread().getName().equals("thread1")) {
                                if (isThread1()){
                                    System.out.println(Thread.currentThread().getName() + "    :   " + i);
                                }else{
                                    this.notify();
                                    this.wait();
                                }
                            } else {
                                if (!isThread1()){
                                    System.out.println(Thread.currentThread().getName() + "    :   " + i);
                                    this.notify();
                                    this.wait();
                                }
                                else{
                                }
                            }
                        } catch (Exception e) {
                        }
                    }
                }
            }
        };
        Thread thread1 = new Thread(runnableObject);
        thread1.setName("thread1");
        thread1.start();
        Thread thread2 = new Thread(runnableObject);
        thread2.setName("thread2");
        thread2.start();
        System.out.println(Thread.currentThread().getName() + "Main thread finished");
    }
}

Silly question, but if thread 2 is supposed to execute when thread 1 is done... why not just start it from thread 1? 愚蠢的问题,但是如果线程2在线程1完成时应该执行...为什么不从线程1开始呢?

Or maybe just have thread 1 trigger an event and the main thread can just launch the new one in response to that. 或者也许只是让线程1触发一个事件,主线程就可以启动新线程来响应。

I found this example, should work for you. 我发现这个例子,应该适合你。

You can run two thread one after other by using several ways: 您可以使用以下几种方法逐个运行两个线程:

  1. by using join() method. 通过使用join()方法。 ex: 例如:

     Thread t1=new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 4; i++) { System.out.println("A " + i); } } }); Thread t2=new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 4; i++) { System.out.println("B " + i); } } }); 
    1. by using wait() and notify() methods: ex. 通过使用wait()和notify()方法:ex。

` `

{
public class NotiffyAllExample {

    int flag = 1;

    public static void main(String[] args) {

        NotiffyAllExample notiffyAllExample = new NotiffyAllExample();

        A1 a = new A1(notiffyAllExample);
        B1 b = new B1(notiffyAllExample);
        C1 c = new C1(notiffyAllExample);
        a.start();
        b.start();
    }
}

class A1 extends Thread {

    NotiffyAllExample notiffyAllExample;

    public A1(net.citigroup.mexico.pg.test.test.NotiffyAllExample notiffyAllExample) {
        this.notiffyAllExample = notiffyAllExample;
    }

    @Override
    public void run() {

        try {
            synchronized (notiffyAllExample) {

                for (int i = 0; i < 4; i++) {

                    while (notiffyAllExample.flag != 1) {
                        notiffyAllExample.wait();
                    }
                    System.out.print("A ");
                }
                notiffyAllExample.flag = 2;
                notiffyAllExample.notifyAll();
            }
        } catch (Exception e) {
            System.out.println("Exception 1 :" + e.getMessage());
        }

    }
}

class B1 extends Thread {

    NotiffyAllExample notiffyAllExample;

    public B1(NotiffyAllExample notiffyAllExample) {
        this.notiffyAllExample = notiffyAllExample;
    }

    @Override
    public void run() {
        try {
            synchronized (notiffyAllExample) {

                for (int i = 0; i < 4; i++) {

                    while (notiffyAllExample.flag != 2) {
                        notiffyAllExample.wait();
                    }
                    System.out.print("B ");
                }
                notiffyAllExample.flag = 1;
                notiffyAllExample.notifyAll();

            }
        } catch (Exception e) {
            System.out.println("Exception 2 :" + e.getMessage());
        }

    }
}
}

` `

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

相关问题 主线程等待其他线程 - Main thread wait for other threads 让主线程等待其他线程完成 - make main thread wait for other threads to finish 如何让主线程在ThreadPoolExecutor中等待其他线程完成 - How to make the main thread wait for the other threads to complete in ThreadPoolExecutor 主线程等待所有线程 isDeamon() 设置假结束 - main thread wait for all threads which isDeamon() set false end 主线程等待两个并行线程子 java - Main thread to wait two parallel threads children java 如何限制创建的线程数并等待主线程,直到任何一个线程找到答案? - How to limit number of threads created and wait main thread until any one thread finds answer? 执行器服务的所有线程都在处理任务时是否可以等待主线程 - Is it possible to wait the main thread while all the threads of executor service are processing tasks 在调用wait和notify之后,我尝试从主线程加入两个线程 - I try to join two threads from the main thread, after calling wait and notify 线程休眠使其他线程等待 - Thread Sleep Makes Other Threads Wait 主/调用线程等待其他线程完成其任务的最佳方式:Thread.sleep()、Latch、CompletableFuture 还是其他? - Best way for main/calling thread to wait for other threads to complete their tasks: Thread.sleep(), Latch, CompletableFuture, or something else?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM