永发信息网

怎样去实现一个无锁的Stack

答案:1  悬赏:0  手机版
解决时间 2021-01-27 22:08
怎样去实现一个无锁的Stack
最佳答案
一个在线2k的游戏,每秒钟并发都吓死人。传统的hibernate直接插库基本上是不可行的。我就一步步推导出一个无锁的数据库操作。

  

  1. 并发中如何无锁。

  一个很简单的思路,把并发转化成为单线程。Java的Disruptor就是一个很好的例子。如果用java的concurrentCollection类去做,原理就是启动一个线程,跑一个Queue,并发的时候,任务压入Queue,线程轮训读取这个Queue,然后一个个顺序执行。

  在这个设计模式下,任何并发都会变成了单线程操作,而且速度非常快。现在的node.js, 或者比较普通的ARPG服务端都是这个设计,逗大循环地架构。

  这样,我们原来的系统就有了2个环境:并发环境 + 地大循环逗环境

  并发环境就是我们传统的有锁环境,性能低下。

  地大循环逗环境是我们使用Disruptor开辟出来的单线程无锁环境,性能强大。

  

  2. 地大循环逗环境 中如何提升处理性能。

  一旦并发转成单线程,那么其中一个线程一旦出现性能问题,必然整个处理都会放慢。所以在单线程中的任何操作绝对不能涉及到IO处理。那数据库操作怎么办看

  增加缓存。这个思路很简单,直接从内存读取,必然会快。至于写、更新操作,采用类似的思路,把操作提交给一个Queue,然后单独跑一个Thread去一个个获取插库。这样保证了逗大循环地中不涉及到IO操作。

  

  问题再次出现:

  如果我们的游戏只有个大循环还容易解决,因为里面提供了完美的同步无锁。

  但是实际上的游戏环境是并发和逗大循环地并存的,即上文的2种环境。那么无论我们怎么设计,必然会发现在缓存这块上要出现锁。

  

  3. 并发与逗大循环地如何共处,消除锁看

  我们知道如果在逗大循环地中要避免锁操作,那么就用逗异步地,把操作交给线程处理。结合这2个特点,我稍微改下数据库架构。

  原本的缓存层,必然会存在着锁,例如:

  public TableCache

  {
  private HashMap caches = new ConcurrentHashMap();
  }

  这个结构是必然的了,保证了在并发的环境下能够准确的操作缓存。但是地大循环逗却不能直接操作这个缓存进行修改,所以必须启动一个线程去更新缓存,例如:

  private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();

  EXECUTOR.execute(new LatencyProcessor(logs));

  class LatencyProcessor implements Runnable

  {

  public void run()
  {

  // 这里可以任意的去修改内存数据。采用了异步。
  }
  }

  OK,看起来很漂亮。但是又有个问题出现了。在高速存取的过程中,非常有可能缓存还没有被更新,就被其他请求再次获取,得到了旧的数据。

  

  4. 如何保证并发环境下缓存数据的唯一正确看

  我们知道,如果只有读操作,没有写操作,那么这个行为是不需要加锁的。

  我使用这个技巧,在缓存的上层,再加一层缓存,成为地一级缓存逗,原来的就自然成为地二级缓存逗。有点像CPU了对不看

  一级缓存只能被地大循环逗修改,但是可以被并发、地大循环逗同时获取,所以是不需要锁的。

  当发生数据库变动,分2种情况:

  1)并发环境下的数据库变动,我们是允许有锁的存在,所以直接操作二级缓存,没有问题。

  2)地大循环逗环境下数据库变动,首先我们把变动数据存储在一级缓存,然后交给异步修正二级缓存,修正后删除一级缓存。

  这样,无论在哪个环境下读取数据,首先判断一级缓存,没有再判断二级缓存。

  这个架构就保证了内存数据的绝对准确。

  而且重要的是:我们有了一个高效的无锁空间,去实现我们任意的业务逻辑。

  

  最后,还有一些小技巧提升性能。

  1. 既然我们的数据库操作已经被异步处理,那么某个时间,需要插库的数据可能很多,通过对表、主键、操作类型的排序,我们可以删除一些无效操作。例如:

  a)同一个表同一个主键的多次UPdate,取最后一次。

  b)同一个表同一个主键,只要出现Delete,前面所有操作无效。

  2. 既然我们要对操作排序,必然会存在一个根据时间排序,如何保证无锁呢看使用

  private final static AtomicLong _seq = new AtomicLong(0);

  即可保证无锁又全局唯一自增,作为时间序列。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
灵心的意思是什么啊?知道的请说下!
谁知道英德市有什么特产和好玩的地方?
三角形的面积的应用题红领巾的底边长是100cm,
我和室友连接同一个路由器,为什么玩红警3局
天津一汽销售服务便利店(张掖甘州区)地址在哪
马里兰州有什么好学校
想学素描 但是没有条件外出上课请老师 只能自
世杰五金店地址有知道的么?有点事想过去
告赛的意思是什么啊?知道的请说下!
“不管黑猫白猫,捉到老鼠就是好猫”这一经典
和史宾格差不多多狗有哪些?
谁有茅山后裔全集txt,谢谢了
关于支气管哮喘,下列叙述哪项是错误的A.儿童
利用因式分解计算:3.68*15.7-31.4+15.7*0.32
鸿达汽车维修中心(张掖民乐县)地址在哪,我要
推荐资讯
病笃乱投医的意思是什么啊?知道的请说下!
怎么办 心情一天好一天不好 变化很大
进入青春期后,许多同学都遇到了一些问题,例
向阳小学(韶关武江区)地址在哪,我要去那里办
罗毕的意思是什么啊?知道的请说下!
时序进度怎么计算
一万平方米等于多少亩
应届毕业生实习期
得月楼茶庄地址在什么地方,我要处理点事
洋洋网咖地址有知道的么?有点事想过去
急!!请问谁知道北京哪家的风干肠,酱驴肉,
湘D·汽车漆面处理连锁服务耒阳西湖店地
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?