Проблема возникает из-за того, что поток t1 зависит от потока t2, а не наоборот.Поток t2 может успешно добавлять элементы в конец списка массивов, не беспокоясь о том, что находится внутри контейнера (при условии, что ArrayList был правильно распределен, как вы это сделали).
Тем не менее, поток t1 зависит от того, что делает поток t2.Например, поток t1 хочет удалить элемент 5 из alist, его возможный поток t2 все еще добавляет '5', и он еще не существует в alist, тогда это вызывает исключение.Затем t1 выдает это исключение и завершает выполнение.Поскольку t2 не зависит от t1 (как описано выше), оно продолжает выполняться до тех пор, пока не будут добавлены все элементы.
Я полагаю, что следующие проблемы обойдут эту проблему:
t2.Start(); // Start t2 thread
t2.Join(); // Wait for thread t2 to add all elements to alist
t1.Start(); // Start t1 thread knowing all elements in alist have been added
t1.Join(); // Wait for thread t1 to complete execution
Если выЯ мог бы попытаться поймать исключение в StartT1 и опубликовать нам точное исключение, которое вы получаете, это может помочь сузить точно, что происходит, но я думаю, что вышеупомянутое наиболее вероятно.
Надеюсь, это поможет.