在网上看到了个帖子如题:有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC… 
自己想尝试下,可才尝试到下面就不知道错在哪里了 
请高手帮忙public class ThreeThread implements Runnable {
Print print = new Print();
public void run() {
for(int i=0;i<10;i++){
//调用打印方法
print.print(Thread.currentThread().getName());
try {
Thread.sleep(1000);

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreeThread test = new ThreeThread();
//创建3个线程对象
Thread a = new Thread(test, "a");
Thread b = new Thread(test, "b");
Thread c = new Thread(test, "c");

a.start();
System.out.println(a.getState());

b.start();
System.out.println(a.getState());
a.notify();

}
}class Print {
public void print(String name) {
System.out.println(name);
}}按我的想法是 想先尝试下通过{a.notify(); } 把进入sleep了的 a唤醒, 
观察得到 a的状态为 TIMED_WAITING  难道这个状态不可以调用 notify方法???
控制台输出如下代码a
RUNNABLE
TIMED_WAITING
b
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at cn.com.Thread.ThreeThread.main(ThreeThread.java:36)
a
b
a
b
a
b请大家帮我看下,或则留下解题思路了 小弟在此谢过。。

解决方案 »

  1.   

    http://topic.csdn.net/u/20100801/12/e5265ef6-eaed-4cf7-a524-1e5592fa5967.html
      

  2.   

    我替楼主改了一点点,测试通过。import java.util.Hashtable;public class ThreeThread implements Runnable {
    Print print = new Print(); Object locka = new Object();
    Object lockb = new Object();
    Object lockc = new Object(); private Hashtable<String, Object> map = new Hashtable<String, Object>(); public ThreeThread() {
    map.put("a", locka);
    map.put("b", lockb);
    map.put("c", lockc);
    } public void run() {
    for (int i = 0; i < 10; i++) {
    String threadName = Thread.currentThread().getName();
    print.print(threadName); Object nextLock = getNextThreadLock(threadName);
    synchronized (nextLock) {
    nextLock.notify();
    } try {
    Object myLock = map.get(threadName);
    synchronized (myLock) {
    myLock.wait();
    }
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    } try {
    Thread.sleep(1000); } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    } private Object getNextThreadLock(String threadName) {
    if (threadName.equals("a")) {
    return lockb;
    } else if (threadName.equals("b")) {
    return lockc;
    } else if (threadName.equals("c")) {
    return locka;
    }
    return null; // It's impossible.
    } public static void main(String[] args) {
    ThreeThread test = new ThreeThread();
    Thread a = new Thread(test, "a");
    Thread b = new Thread(test, "b");
    Thread c = new Thread(test, "c"); a.start(); b.start();
    c.start(); }
    }class Print {
    public void print(String name) {
    System.out.println(name);
    }
    }附:如果楼主吃透这个小例子,那么Thread基本就过关了。
      

  3.   

    “观察得到 a的状态为 TIMED_WAITING 难道这个状态不可以调用 notify方法??”看我的例子, 无论 wait,还是notify,一定要用 synchronized 把这个对象包起来。
    另外,你这个a.nitify();根本就不可能把a唤醒。  a.notify() 只能唤醒哪些正在等待a的线程...(说得不太清楚,楼主还是看代码吧。)
      

  4.   

    用得着那么长的代码么?public class ThreadPrint implements Runnable{
    private String str;

    public ThreadPrint(String str) {
    this.str = str;
    } public void run() {
    System.out.println(str);
    }

    }public class Test {
    public static void main(String[] args) throws InterruptedException {
    while (true) {
    Thread a = new Thread(new ThreadPrint("a"));
    a.start();
    a.join();

    Thread b = new Thread(new ThreadPrint("b"));
    b.start();
    b.join();

    Thread c = new Thread(new ThreadPrint("c"));
    c.start();

    Thread.sleep(1000);
    }
    }
    }
      

  5.   

    3楼的,请你多运行几次你的代码,有时候结果根本都不对的,像这个:
    a
    c
    b
    a
    c
    b
    a
    b
    c
    a
    b
    c
    a
    b
    c
    a
    b
    c
      

  6.   

    如果这是个面试题的话,我想应该要你使用同步的,要不然用不用线程好像都可以实现,呵我也来贴一段
    public class Test2 {
    public static void main(String[] args) {
    Myt myt1 = new Myt("A",0);
    Myt myt2 = new Myt("B",1);
    Myt myt3 = new Myt("C",2);
    myt1.start();
    myt2.start();
    myt3.start();
    }
    }class Myt extends Thread {
    private static Object obj = new Object(); private static int cnt=0;

    private int code; public Myt(String threadName,int code) {
    super( threadName);
    this.code=code;
    } @Override
    public void run() {
    while (true) {
    try {
    synchronized (obj) {
    Thread.sleep(100);
    if(cnt%3==this.code){
    System.out.println(this.currentThread().getName());
    cnt++;
    obj.notifyAll();
    } else{
    obj.wait();
    }

    if(cnt>29){
    break;
    }
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    }
      

  7.   

    给楼主个代码 自己去研究
    public class Exec{
    static Object obj = new Object();
    public static void main(String[] args){
    CharThread ct = new CharThread();
    NumberThread nt = new NumberThread(ct);
    nt.start();
    }
    }
    class NumberThread extends Thread{
    CharThread t;
    public NumberThread(CharThread ct){
    t = ct;
    }
    public void run(){
    synchronized(Exec.obj){
    t.start();
    for(int i = 1;i<=26;i++){
    System.out.println(i);
    try{
    Exec.obj.wait();
    Exec.obj.notify();
    }
    catch(Exception e){}
    }
    }
    }
    }
    class CharThread extends Thread{
    public void run(){
    synchronized(Exec.obj){
    for(char c = 'a';c<='z';c++){
    System.out.println(c);
    try{
    Exec.obj.notify();
    Exec.obj.wait();
    }
    catch(Exception e){} }
    }
    }
    }
      

  8.   

    public class Exec{
    static Object obj = new Object();
    public static void main(String[] args){
    CharThread ct = new CharThread();
    NumberThread nt = new NumberThread(ct);
    nt.start();
    }
    }
    class NumberThread extends Thread{
    CharThread t;
    public NumberThread(CharThread ct){
    t = ct;
    }
    public void run(){
    synchronized(Exec.obj){
    t.start();
    for(int i = 1;i<=26;i++){
    System.out.println(i);
    try{
    Exec.obj.wait();
    Exec.obj.notify();
    }
    catch(Exception e){}
    }
    }
    }
    }
    class CharThread extends Thread{
    public void run(){
    synchronized(Exec.obj){
    for(char c = 'a';c<='z';c++){
    System.out.println(c);
    try{
    Exec.obj.notify();
    Exec.obj.wait();
    }
    catch(Exception e){} }
    }
    }
    }
      

  9.   

    7楼的代码 的意思是这样的么??A,,B,C 三个线程 都start  如果是A拿到CPU时 就能打印,如果是B,C因为传的参数不同,所以即使首先抢到了CPU时 也被直接wait了,然后三个线程又同时去抢线程。
    每个线程只能拿到符合自己特点参数的时候才能执行打印
    这个构思我觉得很不错,虽然没有实际上控制线程顺序,但是控制了线程的方法是否执行。
    看了大家的代码我似乎了解线程一些了。我以前 直接Thread  a =new Thread() , a.wait ,实际上一个线程应该是用来控制其他的方法或则对象的吧 ,所以就像 7楼 的   obj.wait一样。
    希望还有高手来讲解讲解线程,这个特殊的类
      

  10.   


    5楼你的方法能实现,代码也简洁,但你毕竟new 了很多个线程对象啊另外我很好奇那个 join  就是
    start之后就直接调用 join方法 能保证不被其他线程给抢占CPU时 对么??
      

  11.   

    我晕,您这个哪里多线程了???
    join之后那几个线程还有意义么??
      

  12.   

    public class ThreadTest{
    int currentThreadIndex;
    int currentTurn;
    static final int MAX_TURN = 10;  

    public static void main(String[] args){
    String[] threadNames = {"A","B","C","D"};
    ThreadTest threadTest = new ThreadTest();
    for(int i = 0;i < threadNames.length;i++ )
    new Thread(new MyThread(threadNames,i,threadTest)).start();
    }
    }class MyThread extends Thread{
    private String[] threadNames;
    private int threadIndex;
    private ThreadTest threadTest;
    MyThread(String[] threadNames, int threadIndex, ThreadTest threadTest){
    this.threadNames = threadNames;
    this.threadIndex = threadIndex;
    this.threadTest = threadTest;
    }

    public void run() {
    while (true){
    synchronized(threadTest){
    while (threadTest.currentThreadIndex != threadIndex){
    try {
    threadTest.notifyAll();
    threadTest.wait(100);
    if (threadTest.currentTurn == ThreadTest.MAX_TURN)
    break;
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    if (threadTest.currentTurn == ThreadTest.MAX_TURN)
    break;
    System.out.print(threadNames[threadIndex]);
    threadTest.currentThreadIndex = 
    (threadTest.currentThreadIndex + 1)%threadNames.length;
    if (threadIndex == threadNames.length - 1){
    threadTest.currentTurn+=1;
    System.out.print("\n");
    }
    }
    }
    }
    }
      

  13.   


    用join 是理解错题意了 考的是同步 
      

  14.   

    这个是有问题的,一开始三个对象的锁都是可得到的,所有一旦abc三个线程进入run方法的顺序不对就出错了。
      

  15.   

    我也试试啊!!
    public class TestThreadPrint implements Runnable {
        //这个题目得用同步来做,否则就不会是出现以上的结果 (ABC ABC ABC ABC ...)
        public  void run() {
            for (int i=0; i < 10; i++) {
                System.out.print(Thread.currentThread().getName());
               
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }    /**
         * @param args
         */
        public static void main(String[] args) throws InterruptedException {
            // TODO 自动生成方法存根
            TestThreadPrint a = new TestThreadPrint();
            TestThreadPrint b = new TestThreadPrint();
            TestThreadPrint c = new TestThreadPrint();
            Thread ta = new Thread(a); 
            ta.setName("A");
            ta.start();
            Thread.sleep(100);
            Thread tb = new Thread(b); 
            tb.setName("B");
            tb.start();
            Thread.sleep(100);
            Thread tc = new Thread(c); 
            tc.setName("C");
            tc.start();    }}
      

  16.   


    如题:有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC… 没要求通过打印线程名来实现打印ABCABC~~~的顺序吧~~
      

  17.   

    a.notify根本唤不醒a线程啊    况且sleep的线程即使唤醒了也要sleep到指定时间才会继续执行下面的啊
    o(╯□╰)o