《java并发编程实战》随笔——第一章

    最近工作中需要用到并发以提高模块性能,之前对这一块的认识太浅薄并且缺少相关实践,以至于跟大神们讨论方案时经常被问住,遂决定利用空闲时间好好看看并发,多线程,高性能服务器这方面的知识,跟同事交流了下,这块的经典书籍还是不少的,《java并发编程实战》据说是公认的经典,就从它开始吧~

    btw,关于如果选择书籍,我又想起了那句话:重要的不是选择一个最好的开始,重要的是马上立刻现在就开始。


   第一章 简介

   1. 最早

      一台计算机从头到尾只能运行一个程序

   2. 进程出现

       后来,计算机系统在处理多个用户/程序的任务时,采用分片的方式进行调度,即以有限时间片单位执行当前任务后切换到另一个任务继续执行,一个任务可以看做一个进程。之所以这么做,主要原因有两个(书中写了好几个):

       1. 提高资源利用率。想象下A程序在等io时cpu正空闲着,不给B用岂不是浪费?

       2. 公平性。为了使多个用户/程序公平访问计算机资源。

   3. 多线程的优势

       基于与2相同的原因,多线程出现了,但相比多进程有更大的优势,最明显的就是相比操作系统的调度,线程的切换开销很小,并且可以共享进程内的资源,比如内存句柄,文件句柄等。对于现代多处理器 or 多core的单处理器,如果一个程序只有一个线程,那最多就用到了一个core,无法发挥多处理器的全部功力。

       几个多线程的例子:

        1. web程序。假设有若干个请求同时发送到服务器,如果后台服务时单线程的,那一个请求的处理就将阻塞后面一堆请求。但如果为每个请求开一个单独的线程(实际应用中不可能,一般是用线程池),将不存在这样的问题

        2. GUI程序。想象一个cpu密集型的GUI程序,点击按钮会将斐波那契数列(Fibonacci sequence)的第n个数字打出来(n由用户输入),假设计算过程没有缓存,并且使用的是效率奇低的算法,那GUI将被计算过程阻塞,此时用户将无法继续输入,用户体验会很差。

        多线程的需求可以概括为两点:

        1. 关注点分离。 不同线程干不同的事情,方便维护,方便测试。

        2. 提高性能。 这个不用讲了吧?

   4. 多线程的大坑

       多线程似乎很完美,可以共享变量,开销低,性能提高爽歪歪,但别高兴的太早,当你使用的多线程是状态无关时,那还真不会有问题,一旦状态相关那就会随时悲剧,造成非期望的结果。ps:这里的“状态相关“可以理解为是否使用了共享变量。

       一个简单的例子,假设现在有一个将初始值是0的整数n递增5000次的多线程程序,用到了5个线程,每个线程各将n递增1000次这(这个需求很奇怪?yes,仅仅是个例子),好的,现在来写代码,每个线程的c代码可能是这样:

void inc(int *n)
{
  ++*n;
}

       你期望得到的结果是5000, 结果你跑10次出来的结果可能有好几个都不是5000(比5000小),原因在哪里?ok,原因在于这里的n是共享变量,但++*n并不是原子操作,它需要先对n执行自增操作再赋值给自身,考虑线程A对n自增成功的一刹那另一个线程B对其自增并赋值成功,此时A线程再赋值,等于B的自增操作丢失了,这显然不是你期望的结果。

   

   第一章的内容就这么多,很简单,都是学生时代就已经掌握的东东,不过还是把它写了出来,大厦都是根基慢慢打出来的, 下一章见。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值