public class ThreadTest { /**
 * @param args
 */
public static Integer ticket = 1; public static void main(String[] args) { new Thread() { @Override
public void run() { for (int i = 0; i < 50; i++)
loopThread(1);
} }.start(); for (int i = 0; i < 50; i++)
loopThread(0); } public static void loopThread(int id) { // main
synchronized (ticket) {
if (id == ticket && ticket == 0) { System.out.println("loop 100 times for main thread");
                
// switch the ticket to sub thread
ticket = 1;
ticket.notify(); } else if (id == ticket && ticket == 1) { System.out.println("loop 10 times for sub thread");

// switch the ticket to main thread

ticket=0;
                            ticket.notify(); } else {
try {
ticket.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}求教这个问题错在哪?错误是loop 10 times for sub thread
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at ThreadTest.loopThread(ThreadTest.java:45)
at ThreadTest$1.run(ThreadTest.java:16)请不吝赐教,拜谢。线程

解决方案 »

  1.   

    Java要求调用notify/wait/join方法时必须获得对象的内部锁,也就是一定要用synchronized(ticket)。下面代码:
    ticket = 0;
            ticket.notify();
    你在前面synchronized(ticket)的时候ticket = 1,这里你将ticket改成了0,而你并没有持有Integer(0)的内部锁(你持有的是Integer(1))。所以会报错
      

  2.   

    public class ThreadTest {/**
     * @param args
     */
    public static Integer ticket = 1;public static void main(String[] args) {new Thread() {@Override
    public void run() {for (int i = 0; i < 50; i++)
    loopThread(1);
    }}.start();for (int i = 0; i < 50; i++)
    loopThread(0);}public static void loopThread(int id) {// main
    synchronized (ticket) {
    if (id == ticket && ticket == 0) {System.out.println("loop 100 times for main thread");
                    
    // switch the ticket to sub thread
    ticket = 1;
    ticket.notify();} else if (id == ticket && ticket == 1) {System.out.println("loop 10 times for sub thread");// switch the ticket to main threadticket=0;
                                ticket.notify();} else {
    try {
    ticket.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }
    }
      

  3.   

    public class ThreadTest {/**
     * @param args
     */
    public static Integer ticket = 1;public static void main(String[] args) {new Thread() {@Override
    public void run() {for (int i = 0; i < 50; i++)
    loopThread(1);
    }}.start();for (int i = 0; i < 50; i++)
    loopThread(0);}public static void loopThread(int id) {// main
    synchronized (ticket) {
    if (id == ticket && ticket == 0) {System.out.println("loop 100 times for main thread");
                    
    // switch the ticket to sub thread
    ticket = 1;
    ticket.notify();} else if (id == ticket && ticket == 1) {System.out.println("loop 10 times for sub thread");// switch the ticket to main threadticket=0;
                                ticket.notify();} else {
    try {
    ticket.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }
    }
      

  4.   

    public class ThreadTest { /**
     * @param args
     */
    public static Integer ticket = 1;

    private final static  String MESSAGE = "taobao"; public static void main(String[] args) { new Thread() { @Override
    public void run() { for (int i = 0; i < 50; i++)
    loopThread(1);
    } }.start(); for (int i = 0; i < 50; i++)
    loopThread(0); } public static void loopThread(int id) { // main
    synchronized (ticket) {
    if (id == ticket && ticket == 0) { System.out.println("loop 100 times for main thread");
                    
    // switch the ticket to sub thread
    ticket = 1;
    ticket.notify(); } else if (id == ticket && ticket == 1) { System.out.println("loop 10 times for sub thread");

    // switch the ticket to main thread

    ticket=0;
                  ticket.notify(); } else {
    try {
    ticket.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }
    }
      

  5.   

    稍微看了下代码 是Integer 的问题。你每次在调用notify时Integer都已经不是同一个对象了..
      

  6.   

    谢谢各位,integer 不变 改了新值,锁定的对象和物理地址都变了。