Right now I'm experimenting with some basic game concepts in Java. At the moment, all it really does is display two boxes: one that the player can move with the arrow keys, and an "enemy" that just jitters around randomly. Right now, I'm fixing up the player's ability to shoot little squares in the direction of the mouse whenever they click the left mouse button. As it's structured right now, I have four classes - a JPanel that holds the "game" logic, a JFrame that holds that panel, an Entity class which is just a simple representation of a physical object with a position, size, and speed with methods for moving it, and a Projectile class that extends the Entity class with a special move method that moves it one step along a path calculated from the initial and destination points given to the Projectile's constructor.
The problem I'm having is trying to update the position of the projectiles. I have a timer running to update the positions of non-player controlled objects, and the actionPerformed() method of the JPanel has to call every existing projectile's move() method. Right now, when a projectile is created I just put it into a Projectile array with an arbitrarily large size, making sure to start back at [0] when the array is full. The actionPerformed() method can safely act on this array concurrent with the mouse action listener, but since I'm working on this more to learn than to settle with a simple solution that works, I'm wondering if there's a better way to do this than just having an array with size [999]. I tried using an ArrayList at first, but obviously ended up with concurrent access errors. I tried queueing projectiles in an array and then adding them to the ArrayList in the actionPerformed() method, but this gave me null pointer errors.
(TLDR) So my question: Do any of the Java containers (set, map, queue, etc) support concurrent access? I don't think I need a container where order matters, since I have to iterate over every element in the container, I just need a container of a dynamic size that allows one thread to add objects and another to remove/call objects concurrently.