游戏内的知识点

来源:互联网 发布:淘宝联盟能分享到qq群 编辑:程序博客网 时间:2024/05/29 05:54
  1. 内部指令 : InnerMsgType

    客户端指令: 写在MsgType 不需要再手动注册

  2. 热加载的 继承 AbsHotResourceLoader 就
    一般的就 继承 AbsResourceLoader

    配置表:com.share.teplate.gen
    eg :

    @AMF3(res = “BaoShiBuWei.jat”)
    public abstract class BaoshiBuweiTemplateGen {
    @Attribute(“eqpart”)
    private Integer eqpart;//宝石部位

    public Integer getEqpart() {
    return eqpart;
    }

    ……

}

配置service
public class BaoshiBuweiDataTemplateManager extends AbsResourceLoader{

//key 宝石部位 : key 格子号 : templateprivate Map<Integer, Map<Integer, BaoshiBuweiTemplate>> baoshiTemplateMap = new HashMap<>();@Overridepublic void load() throws ServiceException {    。。。。。    baoshiTemplateMap = new ReadOnlyMap<Integer, Map<Integer, BaoshiBuweiTemplate>>(map);}@Overridepublic void checkValid() throws ServiceException {}@Overridepublic String getResName() {    return "BaoShiBuWei.jat";}

}

实体类写在com.share.table 这个注解EntityField 代表不在表中生成字段

  1. 这个AbstractIdleService 可以以后再看 。主要是重启和关闭服务器

    启动
    1 检查数据
    1.1 检查 OperateType中的日志事件是否有重复
    1.2 检查 InnerMsgType 内部指令是否有重复
    1.3 检查 ConsumeYbType 元宝消耗类型是否有重复
    2 加载spring-share的配置文件
    3 在spring-share.xml 中在

    class XXX implements IRunnable{            public void run() {              //这个是上边的提到的@EasyWork的内容              easyManager.execute(cmd, msg);            }    }
      II)然后有个线程一个在循环。LinkedBlockingQueue是先进先出的原则。当没有元素时,线程会一直等待。   public void start(final String name) {    Thread loop = new Thread(name) {        @Override        public void run() {            while (true) {                try {                    IRunnable task = queue.take();                    long start = System.nanoTime();                    task.run();                } catch (Throwable e) {                    logger.error("execute[" + name + "] error", e);                }            }        }    };    loop.start();}          8. 加载info-node.xml         加载         9.缓存             主要是利用guava cache来当缓存的。在获取的时候如果没有这个key时,才会从load中寻找。详见guava cache的代码分析             eg: 插入              1)  先向缓存中插入,然后记录下操作的类型和id                   Map<k,V> map= cache.getUnchecked(new F(classType,...));                   map.put(key, value);                   lock.readLock().lock();                   addType(key,TYPE.INSERT...);                   load.readLock().unLock();              2)刷新到数据库中                       lock.writeLock().lock();                       removeType();                       load.writeLock().unLock();                       T value = cache.getUnchecked(new F(classType,...)).get(key);                        根据操作类型来增删改.                     在什么情况下刷到数据库                     1)) 定时刷新                  ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();                           this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {            @Override            public void run() {                try {                    flush();                } catch (Exception e) {                    LOG.error("loop flush error", e);                }            }        }, FLUSH_PERIOD_SECONDS, FLUSH_PERIOD_SECONDS, TimeUnit.SECONDS);                     2))在jvm退出前,刷新                      public void shutdown() throws InterruptedException {    this.scheduledExecutorService.shutdown();    this.scheduledExecutorService.awaitTermination(FLUSH_PERIOD_SECONDS, TimeUnit.SECONDS);        this.flush();}       redis分全局,游戏,聊天,跨服       在初始化RedisManager 分别建立三个全局,游戏,聊天的redis       如果是游戏服务器        redis订阅发布  可以订阅多个,也可以发布多个        SubScribeManager extends JedisPubSub      下面来看下本服和跨服      1.初始化跨服        从app.properties中的serverId..等创建Server的信息

知识点1: @Component
利用这个可以在包中寻找是带某注解的BeanDefinition
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); // 这个false代表不注册默认的provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
provider.addIncludeFilter(new AnnotationTypeFilter(Table.class)); //这个是这个类中有Table的注解
Set candidates = provider.findCandidateComponents(“com.share.table”); //从这个包中根据IncludeFilter和excludeFilter的规则来获取beanDefinition
以上的这个用于
这个是ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider{
doScan(package) {
Set candidates = findCandidateComponents(package); 这里的IncludeFilter是Component注解
//做些操作再 注册到beanFactory
}

知识点二: redis的订阅和发布,比如在跨服服务器启动的时候发布事件,其所在的本服(本服都对他订阅) 都接收到消息知识点三: BasicDataSource中用到的连接池    GenericObjectPool<T>  pool = new GenericObjectPool<T>(PooledObjectFactory<T> factory, GenericObjectPoolConfig config);    redis中用到的    JedisPool pool = new JedisPool(new GenericObjectPoolConfig(), "192.168.88.62", 6379, 500);    Jedis j = pool.getResource();//从池中取出    j.publish("c", "cccc");    pool.returnResource(j);再放入进去    还有就是跨服已经启动好了,在本服启动的时候试着从连接中取出(连接池没有则会创建),然后再返回到连接池中    以后再用的话,直接从连接池中取出

知识点四:
缓存 :
guava cache 这个源码以后再看。

知识点五:
用aop来实现同步
只要是在cc的模块下,根据这个参数的值来同步

   @Sync(component="cc",index={ 0 })   public void dd(int i) {   } 
 <bean id="syncaspect" class="com.kernel.sync.aop.SyncAspect">        <property name="lockManager" ref="lockManager"/> </bean> <aop:config>     <aop:aspect ref="syncaspect">            <aop:pointcut id="sync" expression="@annotation(com.kernel.sync.annotation.Sync) and @annotation(sync)"/>            <aop:around pointcut-ref="sync" method="sync" arg-names="sync"/>        </aop:aspect></aop:config>
public class SyncAspect   public Object sync(ProceedingJoinPoint pjp, Sync sync) {        //key = 根据模块和参数中的第几个参数值, 从map中得到Lock。只要是Lock相等,就同步进行等.        Lock lock = lockManager.getLock(sync.component(), getLockKey(sync, pjp.getArgs()));        synchronized (lock) {            try {                Object ret = pjp.proceed();                return ret;            } catch (Throwable e) {                throw new RuntimeException("error in sync invoke", e);            }        }    }}

知识点五:
ReentrantReadWriteLock
lock.readLock().lock(); lock.readLock().unlock(); //读锁 可以多个同时读,但是不能写
lock.writeLock().lock(); lock.writeLock().unlock(); //写锁,只能一个人写,不能读
这里只要用到的是Sync
开始写锁:sync.acquire(1);
这里用到了指针, 写入:
创建当前的线程节点,然后放入到尾部.
以后再详解.

    private Node addWaiter(Node mode) {        Node node = new Node(Thread.currentThread(), mode);         Node pred = tail;        if (pred != null) {            node.prev = pred;            if (compareAndSetTail(pred, node)) {                pred.next = node;                return node;            }        }        enq(node);        return node;    }

下面来看下游戏的观后感


  1. Runtime.getRuntime().addShutdownHook(new Thread() {public void run() {}}});
    这个是jvm在关闭前调用的,基本上可以处理一些开启的服务、内存清理等。
    当出现异常退出时操作的,关闭一些开始的服务.防止端口一直被占用或者一些游戏内的缓存数据保存到数据库.
    2.
    guava 的service是管理服务器的启动,关闭和服务器的运行状态。以及处理了在多线程下的状况。
    一般服务器的生命周期包含new,starting,running,stoping,terminated
    eg: AbstractIdleService
    startAsync(),awaitRunning,stopAsync,awaitTerminated
    具体的启动和关闭有子类类实现startUp(),shutDown()
    只有在new的状态下才能使用startAsync()。
    1. 加载
0 0