关于java多线程的问题,有人指点下吗~

qq_37117556 2018-04-28 05:45:07
把Integer当对象传递到每个线程中去进行同步,为什么执行起来在i.notifyAll()处报错。另外,个人对i.notifyAll的理解是:唤醒所有等待使用i这个资源的线程进入就绪状态。我对notifyAll的理解有问题吗?

package t4;

public class test {
public static void main(String[] args) {
Integer i = 40;
t41 t1 = new t41(i);
t41 t2 = new t41(i);
t1.start();
t2.start();
}
}




package t4;

public class t41 extends Thread{
private Integer i;
public t41(Integer i){
this.i = i ;
}

@Override
public void run() {
// TODO Auto-generated method stub
synchronized (i) {
System.out.println(i);
i--;
try {
Thread.sleep(1000);
i.notifyAll();
i.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}



下面是控制台的信息:是说这个i不是对象监视器吗?但是在run方法中已经对i进行同步了啊~

40
40
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at t4.t41.run(t41.java:17)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at t4.t41.run(t41.java:17)

...全文
885 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
用继承Thread 来实现线程的同步,锁默认是类名.class,也可以用一个静态的对象去充当锁。你第一次运行的时候赋值40,那么i=40就是这两个线程的锁。当你i--时改变了锁的值,但是当前锁还是i=40.所有就会报错。把14行注销掉就没有问题了
  • 打赏
  • 举报
回复
wait不能唤醒不属于自己的锁, 在class里面增加一个obj,然后用obj去监控即可, 有一点很重要,加锁不一定要在对象上面,只要每个对象来看锁都是同一把锁即可,建议用一个不变的唯一变量来当锁。 private static Object obj = new Object(); public void run() { // TODO Auto-generated method stub synchronized (obj) { System.out.println(i); i--; try { Thread.sleep(1000L); obj.notifyAll(); obj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
dgqjava 2018-05-02
  • 打赏
  • 举报
回复
12行你的i=40, 你锁定的是40这个i, 14行你进行了i--之后17行i为39, Integer是不可变的类, 因此你的i的值变化了所以对应的对象也变化了, 你锁定的对象和你调用notifyAll的对象已经不是同一个对象了
qq_37117556 2018-04-28
  • 打赏
  • 举报
回复
为什么粘上去之后变成这样了、、、、、

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧