有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java执行两个线程,一个线程等待另一个线程,而主线程继续

我如何启动两个线程,其中thread1首先执行,thread2在thread1结束时启动,而主方法线程可以继续工作,而不锁定其他两个线程

我尝试了join(),但是它需要从线程中调用,而线程必须等待另一个线程,无法执行类似于thread2的操作。连接(thread1); 因此,如果我在main()中调用一个连接,我将有效地停止主线程的执行,而不仅仅是thread2的执行

因此,我尝试了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");
    }
}

#编辑:我为什么需要这个:

我需要这个,因为Thread1将一个数据库表中的元素复制到另一个数据库中,thread2必须复制一个引用从Thread1复制的表的链接表。 因此,只有当thread1完成时,thread2才能开始填充其链接表,否则数据库会给出完整性错误。 现在想象一下,由于复杂的链接表,我有几个优先级不同的线程,你有了一个想法


共 (6) 个答案

  1. # 1 楼答案

    第二个线程可以这样定制(以前一个线程为参数):

    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
        }
    }
    
  2. # 2 楼答案

    我很确定你搞错了,因为这一定行得通,而且确实行得通:

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

    输出为:

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

    另一个选项是,在“线程1”完成自己的工作后,扩展“线程2”的测试线程,以执行“线程2”的工作。类似于此:

    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();
    
  3. # 3 楼答案

    试试这个,它会按预期工作两个线程依次打印奇数和偶数,主线程尽快退出

    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");
        }
    }
    
  4. # 4 楼答案

    为什么不让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();
    

    然而,我们完全不清楚为什么要这样做,而不是让thread1做100%的背景工作

  5. # 5 楼答案

    您可以使用SingleThreadExecutor一个接一个地运行任务Java doc

    所以它会把你的任务一个接一个地放进去,它们会按顺序执行,而不会阻塞主线程

  6. # 6 楼答案

    您可以使用CountDownLatch

    在主线程中创建它,将它传递给两个线程,当它退出时在线程1中调用倒计时,并等待它在线程2的开始处倒计时