webservice并发数设置_Java的并发艺术(一)

笔者在前几天面试的时候就被问到关于并发的一些问题,比如,什么情况下单线程比多线程速度更快?多线程中锁的概念等。下面让我们一起来学习下并发编程。

并发编程的目的是为了让程序运行的更快,提高业务的效率,但是真的是并发就更快吗?是不是启动更多的线程最大限度地去执行,程序就会更快呢?答案是否定的,所以在我们平常编写代码的时候不能想当然的就那么认为,那如何才能合理使用并发,让程序运行的更快呢,首先要了解并发面临着哪些挑战?并发的机制与底层实现原理?下面直接上干货。

并发面临的挑战有:

  1. 上下文的切换
  2. 死锁
  3. 资源限制

什么是上下文切换?举个例子,当我们在读一本英文的技术书时,发现某个单词不认识,于是便打开中英文字典,但是在放下英文技术书之前,大脑必须先记住这本书读到了多少页的第多少行,等查完单词之后,能够继续读这本书。在计算机问世不久的时代,处理器都是单核的,单核处理器也支持多线程,CPU就是通过分配时间片的机制,来回为每个线程做切换执行,每次切换都保存着上一个线程的状态,从任务的执行,保存状态到再一次加载的过程就是一次上下文切换。多核CPU同样要保存着时间片机制。上下文切换是会影响多线程的执行速度的。

用到并发,就会有死锁的情况,什么是死锁?还得先了解下什么是锁,通俗的理解就是一群人运动完之后共同跑到有水喝的房间里去拿水喝,谁先到房间,就把房间锁上,不让后面人进来,喝完再解开锁出去让后面人进去喝。那死锁怎么理解呢?那就是房间里的水是放冰箱里的,冰箱被后面的人锁住了,你得等他拿钥匙,但是你已经把门锁住了,有钥匙的人进不来,就形成了死锁的情况,这样大家都没水喝了。

83c4a9298733f670d4fba8caa4dfbd5c.png

死锁情况

程序中也一样,发生死锁就会造成系统不可用。下面演示下死锁代码。

public class DeadLockDemo { privat static String A = "A"; private static String B = "B"; public static void main(String[] args) { new DeadLockDemo().deadLock(); } private void deadLock() { Thread t1 = new Thread(new Runnable() { @Override publicvoid run() { synchronized (A) { try {  Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (B) { System.out.println("1"); } } } }); Thread t2 = new Thread(new Runnable() { @Override publicvoid run() { synchronized (B) { synchronized (A) { System.out.println("2"); } } } }); t1.start(); t2.start(); } }

何为资源限制?举个例子,服务器的带宽只有2Mb/s,某个资源的下载速度是1Mb/s每秒,系统启动10个线程下载资源,下载速度不会变成10Mb/s,所以在进行并发编程时,要考虑这些资源的限制。硬件资源限制有带宽的上传/下载速度、硬盘读写速度和CPU的处理速度。软件资源限制有数据库的连接数和socket连接数等。资源限制会引发并发问题,如原本是希望代码被并行执行,因受限于资源限制,最终还是串行执行,此时程序反而更慢,增加了上下文切换的开销。

在并发编程中,考虑到并发带来的挑战问题,那如何避免呢?

  1. 结合上下文问题的考虑,可以减少上下文切换的方法,如有无锁并发编程、CAS算法、使用最少线程和使用协程。
  2. 结合死锁情况的考虑,可以避免一个线程同时获取多个锁;避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
  3. 对于硬件资源限制,可以考虑使用集群并行执行程序比如使用ODPS、Hadoop或者自己搭建服务器集群,不同的机器处理不同的数据。可以通过“数据ID%机器数”,计算得到一个机器编号,然后由对应编号的机器处理这笔数据。对于软件资源限制,可以考虑使用资源池将资源复用。比如使用连接池将数据库和Socket连接复用,或者在调用对方webservice接口获取数据时,只建立一个连接。

小结:

并发编程不是一定最快最好,需要结合资源限制,以及编码中自己对锁的理解,并合理利用。

在面试中,如被问到,多线程有哪些缺点的时候,就可以结合该文章回答出个一二啦。

下一节,将会讲并发的底层实现原理。

喜欢小编的文章的可以关注,转发,留言评论,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值