nja*_*jam 6 java multithreading
我需要制作一系列线程.他们需要按照以下顺序开始:
A then B then C and finally D.
D完成后,C可以完成B,然后是A.
在这种情况下使用join()线程还是什么更好wait()?为什么?
我的线程需要启动并打印消息Hello I'm thread a/b/c/d,完成后需要打印I'm finished a/b/c/d.
请记住,join并wait做非常不同的事情,并没有真正相关,并牢记你给出的例子真的,非常奇怪,要么选择可能是你正在寻找的.
join可能是更容易的选择.线程调用join将等待,直到另一个线程完成执行.因此,在这种情况下,每个线程都需要保存对下一个线程的引用,并且它将join在打印"我完成"之前调用.所以你的课可能看起来像这样:
class JoiningThread extends Thread {
// NOTE: UNTESTED!
private String name;
private Thread nextThread;
public JoiningThread(String name) {
this(name, null);
}
public JoiningThread(String name, Thread other) {
this.name = name;
this.nextThread = other;
}
public String getName() {
return name;
}
@Override
public void run() {
System.out.println("Hello I'm thread ".concat(getName()));
if (nextThread != null) {
while(nextThread.isAlive()) {
try {
nextThread.join();
} catch (InterruptedException e) {
// ignore this
}
}
}
System.out.println("I'm finished ".concat(getName()));
}
}
Run Code Online (Sandbox Code Playgroud)
主要方法可能是:
public static void main(String[] args) {
Thread d = WaitingThread("d");
Thread c = WaitingThread("c", d);
Thread b = WaitingThread("b", c);
Thread a = WaitingThread("a", b);
a.start();
b.start();
c.start();
d.start();
try {
a.join();
} catch (InterruptedException e) {}
}
Run Code Online (Sandbox Code Playgroud)
什么wait是暂停执行线程直到notify或被notifyAll调用.所以要实现这个想法wait,你需要每个线程在它之前保存对线程的引用.策略是让run方法完成调用wait,然后调用notify执行完成的前一个线程.所以你的课可能看起来像这样:
class WaitingThread extends Thread {
// NOTE: UNTESTED!
private Thread previousThread;
private String name;
public WaitingThread(String name) {
this(name, null);
}
public WaitingThread(String name, Thread other) {
this.name = name;
this.previousThread = other;
}
public String getName() {
return name;
}
@Override
public void run() {
System.out.println("Hello I'm thread ".concat(getName()));
// Do other things if required
// Wait to be woken up
while(true) {
synchronized(this) {
try {
wait();
break;
} catch (InterruptedException e) {
// ignore this
}
}
}
System.out.println("I'm finished ".concat(getName()));
// Wake up the previous thread
if (previousThread != null) {
synchronized(previousThread) {
previousThread.notify();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
main从主线程设置所有内容的方法可能是:
public static void main(String[] args) {
Thread a = WaitingThread("a");
Thread b = WaitingThread("b", a);
Thread c = WaitingThread("c", b);
Thread d = WaitingThread("d", c);
a.start();
b.start();
c.start();
d.start();
while(true) {
// wake up d once it goes to sleep
if (d.isAlive()) {
d.notify();
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于您正在等待"其他"线程完成(即完成执行),因此join()将是更好的选择.
join()简单地说javadoc :等待这个线程死掉.
这个机制相对简单:
@Override
public void run() {
System.out.println("Hello I'm thread " + getName());
if (otherThread != null) {
while (otherThread.isAlive()) {
try {
otherThread.join();
} catch (InterruptedException e) {
// ignore
}
}
}
System.out.println("I'm finished " + getName());
}
Run Code Online (Sandbox Code Playgroud)
要解释一下:你需要有一个参考otherThread.所以a指b,b指c,c指d并且d不指任何otherThread(它是空的).
该语句otherThread.join()等待另一个线程完成.它被包裹在循环中,因为它join()可以抛出InterruptedException(虽然很少在实践中).
希望这有帮助,祝你好运.
该join()方法用于等待线程完成执行。该join()线程实例的方法可用于“加入”线程的执行开始到另一个线程的执行结束,这样直到另一个线程结束线程将无法启动运行。如果join()在 Thread 实例上调用,则当前运行的线程将阻塞,直到 Thread 实例完成执行。
该wait()方法用于等待在对象上发送通知。这两个条件非常不同。