لماذا notifyAll () رفع IllegalMonitorStateException عندما متزامنة على عدد صحيح؟

StackOverflow https://stackoverflow.com/questions/260337

سؤال

وماذا يفعل هذا نتيجة اختبار البرنامج في java.lang.IllegalMonitorStateException؟

public class test {
    static Integer foo = new Integer(1);
    public static void main(String[] args) {
        synchronized(foo) {
            foo++;
            foo.notifyAll();
        }
        System.err.println("Success");
    }
}

والنتيجة:

Exception in thread "main" java.lang.IllegalMonitorStateException
        at java.lang.Object.notifyAll(Native Method)
        at test.main(test.java:6)
هل كانت مفيدة؟

المحلول

ولقد لوحظ بشكل صحيح يجب استدعاء أن notifyAll من كتلة متزامنة.

ولكن، في قضيتك، بسبب لصناعة السيارات في الملاكمة، الكائن الذي تزامن يوم ليست هي نفسها المثيل الذي قمت باستدعاء notifyAll جرا. في الواقع، لا يزال يقتصر على سبيل المثال foo الجديد، يتزايد إلى المكدس، ويمكن ان يكون قد تم حظره أي مواضيع أخرى على مكالمة wait.

هل يمكن تنفيذ الخاصة، العداد الخاص بك قابلة للتغيير التي يتم تنفيذ التزامن. اعتمادا على التطبيق الخاص بك، قد تجد أيضا أن <لأ href = "http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/AtomicInteger.html" يختلط = " noreferrer "> AtomicInteger يلبي احتياجاتك.

نصائح أخرى

ويجب أيضا أن تكون حذرة من تأمين أو إخطار على الأشياء مثل سلسلة وصحيح يمكن أن يعتقل من قبل JVM (لمنع خلق الكثير من الكائنات التي تمثل العدد الصحيح 1 أو السلسلة "").

وتزايد عدد صحيح يجعل فو القديم تختفي ويتم استبدالها فو كائن جديد العلامة التجارية التي ليست متزامنة مع متغير فو السابق.

وهنا هو تنفيذ AtomicInteger أن إريكسون المقترح أعلاه. في هذا المثال foo.notifyAll ()؛ لا ينتج java.lang.IllegalMonitorStateException beause لا يتم تحديث كائن AtomicInteger عندما foo.incrementAndGet ()؛ تشغيل.

import java.util.concurrent.atomic.AtomicInteger;

public class SynchronizeOnAPrimitive {
    static AtomicInteger foo = new AtomicInteger(1);
    public static void main(String[] args) {
        synchronized (foo) {
            foo.incrementAndGet();
            foo.notifyAll();
        }
        System.out.println("foo is: " + foo);
    }
}

وإخراج:

foo is: 2

وكما لاحظ إريكسون، رمز دون المشغل postincrement يعمل بدون خطأ:

static Integer foo = new Integer(1);

public static void main(String[] args) {
    synchronized (foo) {
        foo.notifyAll();
    }
    System.out.println("Success");
}

والإخراج:

<اقتباس فقرة>   

والنجاح

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top