public class ThreadTest {
/**
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)
请不吝赐教,拜谢。。。。
比如
System.out.println("loop 100 times for main thread");
// switch the ticket to sub thread
ticket = 1;
此处ticket又是个新对象
所以接着调用 ticket.notify(); 会抛刚才的异常 即锁对象不是原来的了
java.lang.IllegalMonitorStateException异常 原因就是当前线程没有获得对象的锁。
此处建议使用AtomicInteger 加 自身的自增完成
如果修改你这个程序,可以
1.加个类
[code="java"]
class Ticket {
Integer value;
public Ticket(Integer value) {
this.value = value;
}
}
[/code]
2.同步对象换成这个类的实例
[code="java"]
// public static Integer ticket = 1;
public static Ticket ticket = new Ticket(1);
[/code]
3.下面的比较和赋值也都是操作Ticket类里面的value,比如
[code="java"]
...
if (id == ticket.value && ticket.value == 0) {
...
ticket.value = 1;
...
[/code]
这样就不会抛异常了。
[b]上面纯粹是学习用的修改,实际开发中不该这么用。[/b]
不过,你这个程序多半也是学习用的吧。哈。