Когда внезапно осознаешь, что твое приложение - многопоточное.Прилетает в sentry такой эксепшен:
java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 0
at java.util.ArrayList.add(ArrayList.java:455)
at java.util.ArrayList.add(ArrayList.java:467)
at com.laravel_idea.plugin.translation.fetching.b.b.a(b.java:24)
Я просто вызываю add() в стандартнейшем классе для списков и получаю странную ошибку. Но крайне редкую. Для тысяч юзеров всего 2 за неделю. В многопотоковом программинге я ноль, но это оно самое. Два потока одновременно пишут в один список и получают ошибку. Вчера еще более странную ошибку находил, с той же самой причиной.
java.lang.ClassCastException: class java.util.HashMap$Node cannot be cast to class java.util.HashMap$TreeNode (java.util.HashMap$Node and java.util.HashMap$TreeNode are in module java.base of loader 'bootstrap')
at java.util.HashMap$TreeNode.moveRootToFront(HashMap.java:1986)
at java.util.HashMap$TreeNode.treeify(HashMap.java:2102)
at java.util.HashMap.treeifyBin(HashMap.java:770)
at java.util.HashMap.putVal(HashMap.java:642)
at java.util.HashMap.put(HashMap.java:610)
at com.laravel_idea.plugin.translation.fetching.b.b.a(b.java:16)
Если данные приватные и пишутся под строгим контролем одного класса, чинить это несложно. Простые конструкции synchronized и все должно быть ок. Также, есть специальные thread-safe структуры данных(ConcurrentHashmap, ConcurrentList). Но внутри у них либо тот же syncronized, либо еще хуже, так что для меня проще так.
synchronized(this) {
vendorData.add(data)
}