Я пытаюсь сделать мою переменную count
synchronized для get
и частной вспомогательной функцией для настройки на основе других членов. Несколько потоков каждый вызывает setCount()
как deadlineNoteVisible
и referencesAvailable
change.
С synchronized
только для setCount()
все в порядке, но когда я добавляю synchronized(this)
get()
вызов get()
, я получаю:
OutOfMemoryError: Failed to allocate a 57993496 byte allocation with 16764448 free bytes and 32MB until OOM
Код (написанный в Котлине):
var count: Int = 0 // Why does adding synchronized here explode? get() = synchronized(this) { count } private set private fun setCount() { synchronized(this) { count = 0 if (deadlineNoteVisible) { count += 1 } if (referencesAvailable) { count += 1 } } }
Трассировки стека:
Error reporting crash java.lang.OutOfMemoryError: Failed to allocate a 57993496 byte allocation with 16764448 free bytes and 32MB until OOM at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95) at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:125) at java.lang.StringBuffer.append(StringBuffer.java:278) at java.io.StringWriter.write(StringWriter.java:123) at com.android.internal.util.FastPrintWriter.flushLocked(FastPrintWriter.java:358) at com.android.internal.util.FastPrintWriter.appendLocked(FastPrintWriter.java:303) at com.android.internal.util.FastPrintWriter.write(FastPrintWriter.java:625) at com.android.internal.util.FastPrintWriter.append(FastPrintWriter.java:658) at java.io.PrintWriter.append(PrintWriter.java:691) at java.io.PrintWriter.append(PrintWriter.java:687) at java.io.Writer.append(Writer.java:198) at java.lang.Throwable.printStackTrace(Throwable.java:324) at java.lang.Throwable.printStackTrace(Throwable.java:300) at android.util.Log.getStackTraceString(Log.java:343) at com.android.internal.os.RuntimeInit.Clog_e(RuntimeInit.java:61) at com.android.internal.os.RuntimeInit.-wrap0(RuntimeInit.java) at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:86) at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler.uncaughtException(CrashlyticsUncaughtExceptionHandler.java:249) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
На самом деле у вас есть StackOverflowError
потому что вы безоговорочно вызываете getCount()
из getCount()
. Я полагаю, что это просто опечатка, и код должен быть:
var count: Int = 0 get() = synchronized(this) { field } private set
Идентификатор field
здесь позволяет вам получить доступ к полю резервного копирования свойства. Вы можете прочитать здесь больше о резервных полях.