多线程锁(Lock)的问题

互联网常常提及的三高问题到底指的是什么? 高性能、高扩展、高并发。

 

“synchronized”锁

实现细节:

1、字节码层面:通过monitorenter和monitorexit指令,就可以实现synchronized了。

2、JVM层面:调用操作系统提供的同步机制。

3、os和硬件层面:实际是lock一条指令。

高性能是互联网三高问题重重之重。我们可以容忍系统较弱的扩展能力,以及系统的并发访问数,往往不能容纳系统极低的性能。

高性能指标一般指两方面的内容:

1、响应时间:低延时

2、吞吐量:高吞吐

“优化系统”一般也是从这两方面入手。所以降低延时,提供吞吐,是我们优化系统的切入点。

Amdahl's law

  • 对系统某部分加速时,其对系统整体影响取决于该部分重要性和加速程度。
  • 要想显著加速整个系统,必须提升全系统中相当大的部分的速度。

如果有一个应用程序完成一项任务需要时间为Told,该应用程序某部分执行时间与总时间比例为α,

若将该部分性能提升k倍,总的执行时间为:

Tnew = (αTold / k) + (Told - αTold)

    = Told [ (1 - α) + α/k ]

加速比 S = Told / Tnew

举几个例子:

集群——>吞吐 

负载均衡——>吞吐 

缓存——>响应

MQ异步——>吞吐

分库分表——>吞吐&响应 

JVM优化——>响应

Tomcat非阻塞协议——>响应

多线程——>吞吐 

注意:加速响应时间的同时,必然会提高吞吐量。大吞吐不一定响应就快。

 多线程:指程序工作过程中开辟多个工作线程来并行操作,以提高系统吞吐量。

那么问题来了,问题一、线程数是越多越好吗?问题二、单核CPU设定多线程是否有意义?问题三、工作线程数设置多少合适?

首先先来回答问题一当然不是越多越好。

  • 服务器CPU核数有限,能够同时并发的线程数有限,单核CPU设置10000个工作线程没有意义

  • 线程切换是有开销的,如果线程切换过于频繁,反而会使性能降低

线程无限创建抛出异常:Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

然后是问题二,单核CPU也可以通过多线程来并发工作,所以单核CPU多线程也是有意义的。单核CPU当某一线程逻辑耗时时间比较长(一些等待的任务实现上如用户输入、文件读写和网络收发数据等),或者由于某种原因挂起,其他线程就会获取到CPU时间片来工作。

JDK演进历程:1.4 1.5 1.6 1.7 1.8 1.9 10 11 12 13 14 15...

多线程三大特性:可见性、有序性、原子性

 

 

/*     */   private Lock getLock(String lockKey) {
/* 167 */     Lock l = (Lock)this.locks.get(lockKey);
/* 168 */     if (l == null) {
/* 169 */       synchronized (this.lock) {
/* 170 */         l = (Lock)this.locks.get(lockKey);
/* 171 */         if (l == null) {
/* 172 */           l = new ReentrantLock();
/* 173 */           this.locks.put(lockKey, l);
/*     */         }
/*     */       }
/*     */     }
/* 177 */     return l;
/*     */   }

 

获取锁代码片段。

 

 

/*     */   private String nextOid(String sid)
/*     */   {
/* 102 */     if (StringUtils.isBlank(sid)) {
/* 103 */       sid = "uapcloud";
/*     */     }
/*     */     
/* 106 */     String key = sid;
/* 107 */     if (StringUtils.isBlank(key)) {
/* 108 */       throw new RuntimeException("schema code can not be null! please check global conf and context info!");
/*     */     }
/*     */     
/*     */ 
/* 112 */     Lock l = getLock(key);
/*     */     
/* 114 */     OidCounter oidCounter = null;
/* 115 */     String oidBase = null;
/* 116 */     String nextOid = null;
/*     */     
/*     */     try
/*     */     {
/* 120 */       l.lock();
/*     */       
/* 122 */       oidCounter = (OidCounter)oidMap.get(key);
/* 123 */       if (oidCounter == null) {
/* 124 */         oidCounter = new OidCounter();
/* 125 */         oidMap.put(key, oidCounter);
/*     */       }
/*     */       
/* 128 */       if ((oidCounter.amount % OID_AMOUNT == 0) || (0 == oidCounter.amount)) {
/* 129 */         oidBase = getNewBaseId(key);
/*     */       } else {
/* 131 */         oidBase = oidCounter.oidBase;
/*     */       }
/*     */       
/* 134 */       nextOid = UapOidAlgorithm.getInstance(oidBase).nextOidBase();
/* 135 */       oidCounter.oidBase = nextOid;
/* 136 */       oidCounter.amount += 1;
/*     */     } catch (Exception e) {
/* 138 */       LOGGER.error("get oid error!", e);
/* 139 */       throw e;
/*     */     }
/*     */     finally {
/* 142 */       l.unlock();
/*     */     }
/*     */     
/* 145 */     if (nextOid == null) {
/* 146 */       return null;
/*     */     }
/*     */     
/* 149 */     return getWholeOid(sid, nextOid);
/*     */   }

 

 

Lock使用代码示例。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江晓曼*凡云基地

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值