2013-07-04 103 views
6

如何启动两个线程,其中thread1首先执行,当thread1结束时线程2启动,而主方法线程可以继续工作而不锁定另外两个线程?我已经尝试过join(),但它需要从线程中调用,必须等待另一个线程,因为没有办法像thread2.join(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"); 
    } 
} 

#EDIT:为什么我需要这样的:

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

+7

你为什么需要2个线程,如果他们强制执行了一个又一个? – Tala

+0

我在上面添加了“为什么我需要这个”。希望它很明确 – dendini

+0

不是真的,没有。 –

回答

3

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

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 
    } 
} 
+0

上面的代码不起作用,只有在第一个完成后,主线才继续运行。我想第二次锁定主体直到第一个还没完成。 – dendini

+0

当然!现在已经修好了 – Tala

3

我敢肯定你有什么问题,因为这必须工作,它的工作:

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 

另一种选择是延长TestThread对于“线程1”在完成自己的工作后执行“线程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(); 
+0

t1.join(); - 主线程将等待t1结束。 – Tala

+1

究竟..我想要主线程继续执行,而不是等待 – dendini

+0

查看更新回答 – darijan

2

您可以使用CountDownLatch:在

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

1

为什么不只是让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%的后台工作。

+0

也许这个显而易见的解决方案太明显了 - 另一个海报建议它,并由于某种原因而被降低了投票率。这肯定是最简单的方式,比明确的信令建议简单得多。 –

0

愚蠢的问题,但如果线程2应该在线程1完成时执行......为什么不从线程1开始呢?

或者,也许只是让线程1触发一个事件,主线程可以启动新的响应。

我发现this的例子,应该为你工作。

+0

这应该是一个评论,而不是答案。 –

+0

什么?这是完成OP所需要的完全合理的方式。 –

+0

..尽管这是一个愚蠢的要求。 –

1

您可以使用SingleThreadExecutor运行陆续Java doc

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

0

您可以相继运行两个线程一个通过使用几种方法:

  1. 通过使用join()方法。例如:

    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); 
         } 
        } 
    }); 
    
  2. 通过使用wait()和通知()的方法:离。

`

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

    } 
} 
} 

`

相关问题