按顺序在两个线程中打印两个不同的字符串

时间:2016-09-15 03:47:58

标签: java multithreading

我正在尝试编写一个程序,其中两个线程同时运行。一个是印刷杰克,另一个是琼斯。预期的产出是: 杰克琼斯杰克琼斯等等。但是在调用 notifyAll()时我遇到了问题。谁能告诉我这是什么问题?

异常

Starting thread
Jack Jones Exception in thread "Thread-0" Exception in thread "Thread-1"    java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at JonesThread.printJones(JonesThread.java:32)
at JonesThread.run(JonesThread.java:14)
java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at JackThread.printJack(JackThread.java:36)
at JackThread.run(JackThread.java:15)

杰克线程

import java.util.concurrent.atomic.AtomicBoolean;

public class JackThread extends Thread {

AtomicBoolean i;

public JackThread(AtomicBoolean i2) {

    this.i = i2;
}

public void run() {
    while (true) {
        try {
            printJack();
            Thread.sleep(10000);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

private void printJack() throws InterruptedException {

    synchronized (i) {
        while (i.get()) {
            {
                wait();
            }
        }

        System.out.print("Jack ");
        i.set(true);
        notifyAll();

    }
}
}

琼斯线程

import java.util.concurrent.atomic.AtomicBoolean;

public class JonesThread extends Thread {

AtomicBoolean i;

public JonesThread(AtomicBoolean i2) {
    this.i = i2;
}

public void run() {
    while (true) {
        try {
            printJones();

            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

private void printJones() throws InterruptedException {
    synchronized (i) {
        while (!i.get()) {
            wait();
        }

        System.out.print("Jones ");
        i.set(false);
        notifyAll();
    }
}
}

MainProgram(主程序)

import java.util.concurrent.atomic.AtomicBoolean;

public class ThreadMain {
public static void main(String args[]) {
    AtomicBoolean i = new AtomicBoolean(false);
    System.out.println("Starting thread");
    JackThread t1 = new JackThread( i); // Will give chance to Print Jack first
    JonesThread t2 = new JonesThread(i);// Jones will follow Jack

    t1.start();
    t2.start();
}
}

1 个答案:

答案 0 :(得分:2)

wait的定义是,如果你说

someObject.wait();

线程会等到有人通知someObject的监视器。另一个线程可以通过调用

来做到这一点
someObject.notify();  // or notifyAll
但事实上,线程必须使用相同的对象进行协调。您尚未指定对象,因此您的wait()等同于

this.wait();

也就是说,JackThread对象正在等待某人通知自己。但是没有人通知JackThread对象。当您JonesThread来电notifyAll()时,它与

相同
this.notifyAll();

所以它通知自己,即一个JonesThread对象。所以基本上,你的两个主题是自己而不是彼此。

您似乎已将i设置为两个线程都知道的对象,因此您可以将其用于waitnotify,即{{ 1}},i.wait()免责声明:我还没有对其进行过测试。