2013-07-14 44 views
0

我正在玩Java中的线程,我对join()方法有疑问。 假设我有一个扩展Thread的SampleClass。我在main中实例化了一些新的线程,但是我想要使用join()顺序完成线程的工作。是否可以在一次调用中调用Thread start()和join()?

public static void main(String[] args) { 
    for(int i=0; i<5; i++){ 
     new SampleClass().start(); 
    } 
} 

是否可以立即调用join()方法? ...这样的事:

new SampleClass().start().join(); 

还是有另一种方法来使用? ......像这样也许:

new SampleClass().start(); 
try{Thread.currentThread().join();}catch(InterruptedException e){...} 

非常感谢您

+0

嗯......这个问题可以通过花2分钟阅读javadocs来回答。 –

+0

我已经看过这里 http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28%29 但我还没有找到任何有用的信息给我。 – Emanuele

回答

1
new SampleClass().start().join(); This is wrong. 

您可以通过

SampleClass samClass = new SampleClass(); 
    samClass.start(); 
    samClass.join() 

上面的代码实现类似的事情都会有你想要的效果相同。

现在你的问题是按顺序运行线程。 在大多数这些 的情况下,你不需要线程顺序执行(但是有一些情况)。 那么如果你不得不。

然后你就可以像这样

Thread t1 = .. 
    Thread t2 = .. 

    t1.start(); 
    t1.join(); 
    t2.start(); // t2 will start only when t1 dies 
    t2.join(); // 
    t3.start(); // t3 will start only when t2 dies.. 

但上面的方法并不好。因为要启动其他线程,需要先前线程 。在实践中,我们应该考虑将线程创建为昂贵的操作 并尝试重用

真正的问题往往就是这样,你必须执行的任务T1,T2,T3,T4 顺序,但在不同的线程T1 & & T3必须在一个线程运行,T2和T4 必须在另一个运行。 所以在这里我们可以使用两个线程而不是4个。 线程1将上 即

Thread1 -> T1 
Thread2 -> T2 
Thread1 -> T3 
Thread2 -> T4 

运行T1,然后线程2将运行T2,然后线程1将运行T3等所有任务将被顺序地但仅使用2个线程执行。

你能解决这个问题,像下面

Thread1 ->run { 
    while(canIrun) { 
    executeTask(taskQueue1.next()); 
    notifyThread2(); 
    waitForThread2Signal(); 
    } 
    } 

    Thread2 -.run { 
    while(canIrun) { 
    waitForThread1Signal(); 
    executeTask(taskQueue2.next()); 
    notifyThread1(); 
    } 
    } 

等待和通知方法可以很容易使用的CyclicBarrier来实现。

+0

谢谢你的时间,写一些例子并给出一些解释。 :-) – Emanuele

1

是否可以立即调用join()方法?

不,它不是start()返回void。你不能以这种方式链接这些方法。你需要在Thread对象上调用join()

+0

好的,谢谢,所以链接是不可能的。假设线程被实例化了,怎么可能(如果可能)调用join()方法呢? Thread.currentThread()join()方法。似乎工作,但不是我所期待的。 第一个线程实例被创建,它完成了工作,但是没有其他事情发生(其他线程没有像FOR只运行一次那样被实例化)。 – Emanuele

0

方法的开始属于Thread类。这将是这样做的:

Thread thread = new Thread(someRunnableTask); 
//This fails to compile, because start returns NOTHING (void). This variable will not be filled with pointer to our thread object. 
Thread ourOriginalThreadPointer = thread.start(); 
//Hence this variable references to nothing, no method can be called. 
ourOriginalThreadPointer.join() 
+0

Err,这是*问题,*不是答案。问题是'start()'返回void,所以你的代码不会被编译,只不过是OP的代码。 -1 – EJP

+0

它应该解释为什么它不会为那些要求知道它如何工作的人编译。学着阅读。我说那里不会编译。 – 2013-07-15 09:16:56

0

instanciated线程不需要是匿名的。你可以这样做:

public static void main(String[] args) { 
    for(int i=0; i<5; i++){ 
     SampleClass sc = new SampleClass(); 
     sc.start(); 
     try { 
      sc.join(); 
     } catch (InterruptedException e) { 
     } 
    } 
} 
1

会是什么意思?你可以通过调用run()来获得相同的效果,没有开销。

+1

+1 - 好点。开始一个线程,并立即加入它,否定了你可能从首先使用线程获得的任何好处。 –

相关问题