黑马程序员技术交流社区
标题:
异常
[打印本页]
作者:
晓天s
时间:
2013-9-16 22:02
标题:
异常
本帖最后由 杨增坤 于 2013-9-17 20:02 编辑
什么时候抛出
InvalidMonitorStateException
异常
?
为什么?
作者:
光脚丫的小白兔
时间:
2013-9-16 22:08
调用 wait ()/notify ()/notifyAll ()中的任何一个方法时,如果当前线程没有获得该对象的锁,那么就会抛出 IllegalMonitorStateException 的异常也就是说程序在没有执行对象的任何同步块或者同步方法时,仍然尝试调用 wait ()/notify ()/notifyAll ()时。由于该异常是 RuntimeExcpetion 的子类,所以该异常不一定要捕获(尽管你可以捕获只要你愿意作为 RuntimeException,此类异常不会在 wait (),notify (),notifyAll ()的方法签名提及。
作者:
2012
时间:
2013-9-16 22:27
1、什么时候抛出InvalidMonitorStateException 异常,为什么?
答:调用wait ()/notify ()/notifyAll ()中的任何一个方法时,如果当前线程没有获得该对象的锁,那么就会抛出IllegalMonitorStateException 的异常(也就是说程序在没有执行对象的任何同步块或者同步方法时,仍然尝试调用wait ()/notify ()/notifyAll ()时)。由于该异常是RuntimeExcpetion 的子类,所以该异常不一定要捕获。作为RuntimeException,此类异常不会在wait (),notify (),notifyAll ()的方法签名提及。
2、在静态方法上使用同步时会发生什么事?
答:同步静态方法时会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。
3、当一个同步方法已经执行,线程能够调用对象上的非同步实例方法吗?
答:可以,一个非同步方法总是可以被调用而不会有任何问题。实际上,Java 没有为非同步方法做任何检查,锁对象仅仅在同步方法或者同步代码块中检查。如果一个方法没有声明为同步,即使你在使用共享数据Java 照样会调用,而不会做检查是否安全,所以在这种情况下要特别小心。一个方法是否声明为同步取决于临界区访问(critial section access),如果方法不访问临界区(共享资源或者数据结构)就没必要声明为同步的。
希望对你有所帮助!
作者:
yanglfree
时间:
2013-9-16 23:23
我上次写代码的时候因为漏掉了关键字synchronied导致出现了这个异常
记得很清楚
作者:
比烟花寂寞_neve
时间:
2013-9-17 02:01
调用 wait ()/notify ()/notifyAll ()中的任何一个方法时,如果当前线程没有获得该对象的锁,那么就会抛出 IllegalMonitorStateException 的异常(也就是说程序在没有执行对象的任何同步块或者同步方法时,仍然尝试调用 wait ()/notify ()/notifyAll ()时)。由于该异常是 RuntimeExcpetion 的子类,所以该异常不一定要捕获(尽管你可以捕获只要你愿意).作为 RuntimeException,此类异常不会在 wait (),notify (),notifyAll ()的方法签名提及。
作者:
hanfei2511
时间:
2013-9-17 06:08
其他人已经解释的很好了,在这里,我找了个不错的例子给你看,希望对你有帮助。
class IllegalMonitorStateExample
{
public static void main(String a[])
{
AnObject o = new AnObject();
Thread inc = new Thread(new IncrUser(o));
Thread dec = new Thread(new DecrUser(o));
inc.start();
dec.start();
}
}
class IncrUser implements Runnable
{
AnObject a ;
IncrUser()
{
}
IncrUser(AnObject a)
{
this.a = a;
}
public void run()
{
while(true)
{
try
{
[B]// a.wait();[/B]
a.incr();
Thread.sleep(1000);
[B] // a.notify(); //[/B]
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
}
}
class DecrUser implements Runnable
{
AnObject a ;
DecrUser()
{
}
DecrUser(AnObject a)
{
this.a = a;
}
public void run()
{
while(true)
{
try
{
a.decr();
Thread.sleep(1000);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
}
}
class AnObject{
int myNum = 0;
synchronized void incr() throws InterruptedException
{
if(myNum!=0)
{
System.out.println("ready to incr but muNum not zero +++++++++++++++");
wait();
}
myNum++;
print("produced : ");
notify();
}
synchronized void decr() throws InterruptedException
{
if(myNum==0)
{
System.out.println("ready to decr but myNum not 1 ----------");
wait();
}
myNum--;
print("consumed : ");
notify();
}
void print(String s)
{
System.out.println(s + " "+myNum);
}
}
作者:
(0.0)’
时间:
2013-9-17 07:52
对于是否抛出异常,首先要判断继承的父类是否抛出了该异常,如果没有,子类是不可以抛出该异常的。
如果父类没有抛出该异常或抛出的不是该异常的父类,则需要在此类的子类中try-catch。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2