游戏多人对战匹配功能代码,要注意线程安全

package com.server.littlegame;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;

import com.server.sharedata.SharedFunc;

public class TstGameDataManager {

    public static class RoleData {
        String id = "";

        public String getid() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        int type = 0;

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        String name;

        public String getname() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    private static final Logger log = SharedFunc.getLogger(TstGameDataManager.class);
    static List<RoleData> curList = Collections.synchronizedList(new ArrayList<RoleData>());// 匹配列表
    static Map<String, String> matchMap = new ConcurrentHashMap<>();// 已配对列表

    public static void InBattle(RoleData role) {
        synchronized (curList) {
            if (role != null) {
                curList.add(role);
                log.info(role.getname() + "进入匹配");
                CheckRepeat();
            }
        }
    }

    public static void OutBattle(RoleData role) {
        synchronized (curList) {
            if (role != null) {
                curList.remove(role);
                log.info(role.getname() + "退出匹配");
                CheckRepeat();
            }
        }
    }

    public static void RemoveMatchMap(RoleData role) {
        if (role != null) {
            matchMap.remove(role.getid());
            log.info(role.getname() + "移除匹配");
        }
    }

    public static RoleData Matching(RoleData role) {
        synchronized (curList) {

            if (curList.size() == 0) {
                return null;
            }

            if (!curList.contains(role)) {
                log.info(role.getname() + "已经被匹配走了");
                return null;
            }

            RoleData rival = null;

            for (RoleData obj : curList) {
                if (!obj.equals(role)) {
                    if (role.getType() == obj.getType()) {
                        rival = obj;
                        break;
                    }
                }
            }

            // 记录,并从匹配列表移除
            if (rival != null) {
                log.info(role.getname() + " 匹配到 " + rival.getname());
                matchMap.put(role.getid(), role.getid());
                matchMap.put(rival.getid(), rival.getid());
                OutBattle(rival);
                OutBattle(role);
            }

            return rival;
        }
    }

    public static void CheckRepeat() {
        Map<String, Integer> map = new HashMap<String, Integer>();

        for (String k : matchMap.keySet()) {
            if (map.containsKey(k)) {
                map.put(k, map.get(k) + 1);
                if (map.get(k) >= 3) {
                    log.info(k + "重复");
                }
            } else {
                map.put(k, 1);
            }
            String v = matchMap.get(k);
            if (map.containsKey(v)) {
                map.put(v, map.get(v) + 1);
                if (map.get(v) >= 3) {
                    log.info(v + "重复");
                }
            } else {
                map.put(v, 1);
            }
        }
        log.info("待匹配人数:" + curList.size() + " 配对数:" + matchMap.size() / 2);

        // 在遍历集合,删除集合元素过程中有其他线程改变了该集合时会抛出异常java.util.ConcurrentModificationException
        for (RoleData role : curList) {
            System.out.print(role.getname() + "|");
        }
    }

    public static void main(String[] args) {
        final Random r = new Random();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    int type = r.nextInt(5);
                    RoleData role = new RoleData();
                    role.setType(type);
                    role.setName("A" + type + i);
                    role.setId("A" + type + i);
                    InBattle(role);
                    Matching(role);
                }
            }
        }).start();
        new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    int type = r.nextInt(5);
                    RoleData role = new RoleData();
                    role.setType(type);
                    role.setName("B" + type + i);
                    role.setId("B" + type + i);
                    InBattle(role);
                    Matching(role);
                }
            }
        }).start();
    }
}