我希望线程按顺序打印出它们的名称。输出应如下所示:
线程-0
线程1
线程2
线程3
线程4
线程5
线程1
线程2
线程3
public class NameOutput extends Thread {
static final int N = 5;
static int activeThread = 0;
public static void main(String[] args){
for (int i = 1; i <= N; i++) {
new NameOutput().start();
}
}
@Override
public void run(){
while(true){
this.printThreadName();
}
}
private synchronized void printThreadName(){
String threadName = "Thread-"+ activeThread;
//Check if thread is in the right order
if(!threadName.equals(this.getName())){
try{
wait();
}catch (InterruptedException e){
System.out.println(this.getName()+" was interrupted!");
}
}else{
System.out.println(this.getName());
activeThread = (activeThread + 1) % N;
notifyAll();
}
}
}
不知何故,如果首先选择Thread-0,那么输出就是Thread-0。在第一个线程等待之后,程序将停止。
答案 0 :(得分:2)
问题是您创建了多个NameOutput
,并且它们使用their own monitor lock,这意味着它们之间将没有“通信”(信号)。
相反,您需要共享的监视器锁定:
public class NameOutput extends Thread {
static final int N = 5;
static int activeThread = 0;
static final Object lock = new Object(); // shared monitor lock
public static void main(String[] args){
for (int i = 1; i <= N; i++) {
new NameOutput().start();
}
}
@Override
public void run(){
while(true){
this.printThreadName();
}
}
private void printThreadName(){
synchronized (lock) {
String threadName = "Thread-"+ activeThread;
//Check if thread is in the right order
if(!threadName.equals(this.getName())){
try{
lock.wait();
}catch (InterruptedException e){
System.out.println(this.getName()+" was interrupted!");
}
}else{
System.out.println(this.getName());
activeThread = (activeThread + 1) % N;
lock.notifyAll();
}
}
}
}
另一个问题,wait
should总是在while
循环中使用,您可以做更多的事情:
private void printThreadName(){
synchronized (lock) {
while (!("Thread-"+ activeThread).equals(this.getName())) {
try{
lock.wait();
}catch (InterruptedException e){
System.out.println(this.getName()+" was interrupted!");
}
}
System.out.println(this.getName());
activeThread = (activeThread + 1) % N;
lock.notifyAll();
}
}
输出:
Thread-0
Thread-1
Thread-2
Thread-3
Thread-4
Thread-0
Thread-1
Thread-2
Thread-3