IllegalMonitorStateException这个东西搞得我烦死了。notify、wait、notifyAll都必须在synchronized块里执行要么是synchronized函数,那么同步锁锁定的要么是this,要么是Class(static函数)要么是synchronized块,如下:
synchronized (this) {
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(NewClass2.class.getName()).log(Level.SEVERE, null, ex);
}
}这个肯定没问题,但是如果是
synchronized ("someObject") {
try {
"someObject".wait();
} catch (InterruptedException ex) {
Logger.getLogger(NewClass2.class.getName()).log(Level.SEVERE, null, ex);
}
}
synchronized ("someObject"),那么一定只能调用"someObject"的wait、notify等等(当然,字符串常量是同一对象,这里的字符串常量可以换成任何对象)
这里就搞得很糊涂。 This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways: * By executing a synchronized instance method of that object.
* By executing the body of a synchronized statement that synchronizes on the object.
* For objects of type Class, by executing a synchronized static method of that class.
Object类里头notify的解释也不是很明白。有没有达人解释一下?
synchronized (this) {
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(NewClass2.class.getName()).log(Level.SEVERE, null, ex);
}
}这个肯定没问题,但是如果是
synchronized ("someObject") {
try {
"someObject".wait();
} catch (InterruptedException ex) {
Logger.getLogger(NewClass2.class.getName()).log(Level.SEVERE, null, ex);
}
}
synchronized ("someObject"),那么一定只能调用"someObject"的wait、notify等等(当然,字符串常量是同一对象,这里的字符串常量可以换成任何对象)
这里就搞得很糊涂。 This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways: * By executing a synchronized instance method of that object.
* By executing the body of a synchronized statement that synchronizes on the object.
* For objects of type Class, by executing a synchronized static method of that class.
Object类里头notify的解释也不是很明白。有没有达人解释一下?
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(NewClass2.class.getName()).log(Level.SEVERE, null, ex);
}
}
这个等于
synchronized (this) {
try {
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(NewClass2.class.getName()).log(Level.SEVERE, null, ex);
}
}
你用了同步代码块 就要用 obj.wait(); 和 obj.notify啊 我真不知道LZ哪里有问题了哇 随便讲了点哇 LZ别笑哇
我的意思是:用了synchronized ("someObject") ,是不是只能用"someObject"的wait、notify和notifyall?
为啥?还有,那个jdk当中的鸟语到底是啥意思。。
* By executing the body of a synchronized statement that synchronizes on the object.
* For objects of type Class, by executing a synchronized static method of that class. 这个方法只能被一个有对象监视器的线程去调用。一个线程可以在以下3中方式中拥有对象的监视器 1. 执行那个obj的一个同步的实例方法
2. 执行同步了对象的同步代码块中的代码
3. 对于obj类型的类 要执行那个类中的同步的静态方法翻译得很烂哇 就这个水平了额
synchronized ("someObject")中的"someObject"类似一把锁,只有得到这把锁的线程才允许对此锁进行操作.
线程等待在这里,直到轮到它拥有锁后,进入同步块代码处理,但在同步块代码中不保证该线程拥有其它锁,
所以不能操作其它锁的wait(),notify()等.否则容易产生死锁现象.
synchronized 除了可以修饰对象外,还是可以写是方法的。 首先是synchronized关键字的作用域可以有两种:・某个对象实例内synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)・某个类的范围synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法●synchronized关键字是不能继承的●要注意的事项・无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问・每个对象只有一个锁(lock)与之相关联・实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制●对共享资源的同步访问更加安全的技巧・定义private 的instance变量+它的 get方法,而不要定义public/protected的instance变量。如果将变量定义为public,对象在外界可以绕过同步方法的控制而直接取得它,并改动它。・如果instance变量是一个对象,如数组或ArrayList什么的,那上述方法仍然不安全,因为当外界对象通过get方法拿到这个instance对象的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。 这个时候就需要将get方法也加上synchronized同步,并且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了。
说当前线程不是monitor的所有者.
notify()必须放在同步块内
synchronized(rende){
rende.notify();
}
呢?有下列三种线程:
1:正在执行该对象的同步方法的线程;
2:正在执行同步块的,并且在该对象上边同步的同步块的语句;//答案应该在这句
3:对于是class类型的对象,正在执行该类的静态同步方法的线程;
public class A{
public synchronized method(){//执行这个方法的线程拥有this就是当前对象的监视器
}
public void method(){
synchronized(Someobject){
//执行这个语句块的线程拥有someobject的监视器
}
}
public static method(){
//执行这个方法的线程拥有A.getClass()对象的监视器
}
}大概是这样
这个方法(由后面的对象调用)应该只有在持有该对象的锁的线程里调用。A thread becomes the owner of the object's monitor in one of three ways:
一个线程持有这个对象的锁的三个途径:1.By executing a synchronized instance method of that object.
通过执行这个对象的一个同步方法。
2.By executing the body of a synchronized statement that synchronizes on the object.
通过执行 在这个对象上同步的同步语句块。
3.For objects of type Class, by executing a synchronized static method of that class.
抛开具体对象,对Class进行同步。通过执行类的一个静态同步方法。
此时获得的锁,对所有这个类的具体对象有效。翻译水平很烂,凑合看吧。
有几个英文单词没具体翻译。
wait()
notify()
notifyAll()
这三个方法相当于门,而synchronized这个东东是用来获得钥匙的
如果你用synchronized(this)
{
obj.wait();
}
就是相当于用this这把钥匙想要去开obj的门,这是不允许的。
Synchronized(key){门里的东西},所以这么门只认识这个钥匙,决定这个门的开关是由这个key决定的,别人的key事没有用的,所以key.wait(),就事放弃这个门的钥匙,并且停在了代码原处,别人也会需要这把钥匙来开自己的门,别人就会拿到这把钥匙,直到有人调用了key.notify,我们才能继续往下执行