Java同步字符串IllegalMonitorStateException
我试图让Thread2等待字符串和Thread1在字符串更新时通知,我确实同步了字符串对象,如下面的代码所示,但我仍然得到Java同步字符串IllegalMonitorStateException,java,multithreading,blackberry,Java,Multithreading,Blackberry,我试图让Thread2等待字符串和Thread1在字符串更新时通知,我确实同步了字符串对象,如下面的代码所示,但我仍然得到IllegalMonitorStateException这是我的代码 public class Class1{ String string = ""; public Class1(){ Thread t1 = new Thread(){ public void run(){ synchronized(stri
IllegalMonitorStateException
这是我的代码
public class Class1{
String string = "";
public Class1(){
Thread t1 = new Thread(){
public void run(){
synchronized(string){
string = "Something"; string.notifyAll(); //This is the line that throws an IllegalMonitorStateException
}
}
};
Thread t2 = new Thread(){
public void run(){
synchronized(string){
try{
string.wait();
}catch(Exception e){
e.printStackTrace();
}
}
}
};
t2.start();
t1.start();
}
}
StackTrace中除了突出显示string.notifyAll()
synchronized
块外部的可变字符串
变量。具体来说,这发生在synchronized(string)
行上。当取消引用字符串
以到达监视器将被锁定的对象时,线程尚未锁定该对象。因此,您无法保证它将锁定哪个对象字符串
变量进行了变异,这意味着它现在指向其他对象。当下一个线程获得该新对象的锁时,它将不会从任何before关系中受益,因为它是第一个获得该对象锁的线程。互斥也不能保证,因为可能有任意多个线程,每个线程都锁定一个不同的String
实例,而没有争用synchronized(string)
行上到达的对象与在synchronized块内到达的对象相同。一旦这确实是一个不同的对象,您的IllegalMonitorStateException
就会随之发生synchronized
块
如果您坚持使用专用的final
变量引用用于锁定的对象的最佳实践,则可以避免上述所有问题。简而言之,为了修复示例中的编译错误,您必须编写以下内容:
static String string = "";
static final Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread() {
public void run() {
synchronized (lock) {
... update the string variable ...
lock.notifyAll();
}
}
};
Thread t2 = new Thread() {
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
t2.start();
t1.start();
}
我没有收到任何
IllegalMonitorStateException
。当您谈论“字符串更新”时,必须假设变量String
表示的实例发生了更改(当然,您提供的代码不是导致错误的代码)@Braj我想这可能是BlackBerry的问题@Marco13是的,我正在更改string
@Downvoter的值。请留下评论,这个答案有什么问题?它可以改进吗?@meLovefinal
的主要目的是阻止你更新它。这个答案有点误导。添加final
并不能解决您的问题-您的问题通过不更新变量得到部分解决,而final
强制执行该变量。@immibis我相信代码示例会尽可能清楚地给出这个答案。或者你能建议我如何进一步改进它吗?@WilliamF.Jameson“你的问题很可能是由于在一个非final
变量上进行同步造成的”-变量是否final
无关紧要;重要的是值是否更改。@immibis OK,我删除了它,但我认为这是毫无意义的,因为1)如果锁定final
变量,异常肯定会消失;2) 始终锁定专用的最终
变量是最佳实践,因此问题是由于未能遵循该最佳实践而产生的;3) 始终存在非最终变量可能在某个地方发生更改的风险,或此类代码可能在以后引入的风险;所以,即使你目前没有症状,如果你锁定一个非最终变量,这仍然是一个问题;4) 您可能存在非最终变量的安全发布问题。