arynaq
arynaq

Reputation: 6870

Concurrency issues and hashmap

I am starting to think about multithreading for my game and the best place to start would be to seperate the three main components of the game: logic, gfx, sfx, into 3 seperate threads. The problem is they all need to access the same hashmap of entities as the logic, gfx and sfx are completely seperate from eachother.

private Map<String, Entity> entities;
private Map<String, GameSound> sounds;
private Map<String, ArrayList<BufferedImage>> images;

The same hashmap is passed around to the different classes and object corruption is very likely with multiple threads. Currently the SoundsEngine is the one threaded (else the music pauses between Thread.sleep() and that is fine as it doesn't change, it just reads.

Is there an easy (and not hardhitting on performance) way to implement a threadsafe HashMap without adding synchronized all over my code (and probably introducing more bugs this way)? I thought about taking a shallow copy every 60 frames as that is the maximum rate anything in my game will change and passing the copy around in the gameloop to the different engines but that seems a bity "hacky".

The concurrency problem is show by the constructors in the factory:

public class Factory {

    private Map<String, Entity> entities;
    private Map<String, GameSound> sounds;
    private Map<String, ArrayList<BufferedImage>> images;
    private GameEventListener listener;
    private GameFrame frame;
    private ImageLoader Iloader;
    private SoundLoader Sloader;


    public Factory() {
        this.Iloader = new ImageLoader("imagelist.txt", images);
        this.Sloader = new SoundLoader("soundlist.txt", sounds);
        this.frame = new GameFrame(Color.black);
        this.listener = new GameEventListener();
    }

    public GameEngine createGameEngine() {
        return new GameEngine(entities, images, sounds);
    }

    public SoundEngine createSoundEngine() {
        return new SoundEngine(entities, sounds);
    }

    public GraphicsEngine createGraphicsEngine() {
        return new GraphicsEngine(entities, frame);
    }
}

Edit: Singletons not an option, already did that in a previous game, I want to learn a more "loose" design in which I can independently develop the engines without breaking something because I have the wrong state.

Upvotes: 2

Views: 453

Answers (2)

Charly
Charly

Reputation: 303

Using ConcurrentHashMap is better as it does not use synchronized block. It is so more efficient and faster. Collections.synchronizedMap is a proxy where a synchronized block will be added to each method call.

Upvotes: 1

Vishal K
Vishal K

Reputation: 13066

If you want to get synchronized version of your Hashmap then you can use the following inbuilt method of java.util.Collections class:

Map m = Collections.synchronizedMap(new HashMap(...));

Apart from that java.util.concurrent.ConcurrentHashMap is a better option for you.

Upvotes: 4

Related Questions