简体   繁体   English

Java synchronized String IllegalMonitorStateException

[英]Java synchronized String IllegalMonitorStateException

I'm trying to have a Thread2 wait for a String and Thread1 to notify on String update, I do synchronize The String object as code below shows, But I still get IllegalMonitorStateException Here's my code 我正在尝试使用Thread2等待String和Thread1通知String更新,我执行同步String对象,如下面的代码所示,但我仍然得到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();
}

}

There's nothing in StackTrace except highlighting string.notifyAll() 除了突出显示string.notifyAll()之外,StackTrace中没有任何内容

  1. Your code contains a data race because it accesses the mutable string variable outside of a synchronized block. 您的代码包含数据争用,因为它访问synchronized块之外的可变string变量。 Specifically, this happens on the line synchronized(string) . 具体来说,这发生在synchronized(string)synchronized(string) While dereferencing string to reach the object whose monitor will be locked, the thread does not already hold a lock on that object. 取消引用string以到达其监视器将被锁定的对象时,该线程尚未锁定该对象。 Therefore you have no guarantee which object it will acquire a lock on. 因此,您无法保证它将锁定哪个对象。

  2. The fact that you mutate the string variable means that it now points to some other object. 改变 string变量这一事实意味着它现在指向其他一些对象。 When the next thread acquires a lock on that new object, it will not benefit from any happens-before relationship because it is the first thread to ever acquire a lock on it. 当下一个线程获得对该新对象的锁定时,它将不会受益于任何发生在之前的关系,因为它是第一个获得锁定的线程。 Mutual exclusion will not be guaranteed, either, because there may be arbitrarily many threads, each locking a different String instance without contention. 也不保证相互排斥,因为可能有任意多个线程,每个线程锁定不同的String实例而没有争用。

  3. Combining the two phenomena described above we can also see that there is no guarantee that the object reached on the line synchronized(string) will be the same one as the one reached from within the synchronized block. 结合上述两种现象,我们还可以看出,无法保证在synchronized(string)线synchronized(string)上到达的对象与从同步块到达的对象相同。 Once it happens that this is indeed a different object, your IllegalMonitorStateException ensues. 一旦发生这确实是一个不同的对象,就会发生IllegalMonitorStateException

In summary, the situation is very similar to the synchronized block not existing at all. 总之,情况非常类似于根本不存在的synchronized块。

All of the above problems can be avoided if you keep to the best practice of using dedicated final variables to refer to objects used for locking. 如果您始终遵循使用专用final变量来引用用于锁定的对象的最佳实践,则可以避免上述所有问题。 In a nutshell, and fixing the compilation errors in your example, this is what you would have to write: 简而言之,在您的示例中修复编译错误,这是您必须编写的内容:

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java 同步:IllegalMonitorStateException - Java synchronized : IllegalMonitorStateException 从同步块中调用wait时发生java.lang.IllegalMonitorStateException - java.lang.IllegalMonitorStateException whilst calling wait from synchronized block @Synchronized 方法中的 Kotlin IllegalMonitorStateException - Kotlin IllegalMonitorStateException in @Synchronized method 同步块中的IllegalMonitorStateException - IllegalMonitorStateException inside synchronized block IllegalMonitorStateException Java - IllegalMonitorStateException Java 在Integer上同步时notify()上发生IllegalMonitorStateException - IllegalMonitorStateException on notify() when synchronized on an Integer 当我以静态方式同步块调用wait()时,为什么Java会抛出java.lang.IllegalMonitorStateException? - Why Java throw java.lang.IllegalMonitorStateException when I invoke wait() in static way synchronized block? baton.notifyAll给出java.lang.IllegalMonitorStateException尽管同步(蝙蝠) - baton.notifyAll gives java.lang.IllegalMonitorStateException despite synchronized(baton) 同步内Thread.notify()上的IllegalMonitorStateException - IllegalMonitorStateException on Thread.notify() within synchronized 同步调用Lock Condition的signalAll()时发生IllegalMonitorStateException - IllegalMonitorStateException on a synchronized call to a Lock Condition's signalAll()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM