zoukankan      html  css  js  c++  java
  • 2018/12/5 彻底搞懂多线程和线程安全

    早起占坑


     多线程问题,先要搞清楚两个概念:

    并发(concurrent):并发指宏观上同时进行,微观上同一时刻只有一个任务在执行。一般指单核多线程下为并发。

    并行(parallel):并行指宏观上同时进行,微观上同一时刻确实是多个任务同时执行。多核处理器可以并行执行多个任务。

    为什么需要多线程呢?

    可以拿分时多用户操作系统来理解,我们的电脑为什么可以同时听歌、放电影、看网页,,,并不是因为电脑中有多个处理器在分别干这个事情,

    而是操作系统将处理器分成一个个小的时间片,这些任务轮换着使用时间片,因为时间片的切换速度非常快,可能一秒内可以切换几百万次时间片,

    而CPU的处理速度也同样非常快,可能程序中的一个小的交互任务只需要一两个、十个八个时间片,对用户来说,这么快速的处理和切换是感受不到的,

    所以,实现了一个CPU同时处理多个任务,而不是排队处理任务。

    试想我们顺序执行听歌、放电影、看网页,对用户的排队等待时间是个极大的浪费,对CPU等待用户交互的时间也是极大的浪费,应该在这个任务等待的时间去处理其它任务。

    在一个程序进程中的线程也是同样的道理,如果进程内的一个交互任务可以切换成许多个小的任务,比如多文件的读写,或边读文件边相应用户其它操作,

    同样可以通过时间片的轮转同时进行不同的任务或相同任务的拆分,多线程提高了CPU的利用率,节省了用户的等待时间,提高CPU的利用率,提高了整体工作效率。

    以后理解多线程,就可以拿听歌、看电影、看网页来理解。

    正是CPU的运力极高,由于听歌、看电影并不会占用百分百的CPU时间,所以可以利用CPU闲时并发处理更多的任务,

    如果是多个纯CPU运算任务,并发并不会减少计算的总时间,甚至会略有延长,但是多任务共同推进,对用户更加友好。

    当然日常应用中绝大多数的任务都存在io等非CPU操作,所以,在这些任务中使用并发可以提高程序运行效率。

    使用并发提对我们来说提高了啥?优点

    1.减少响应时间,提升用户体验。可以对每个任务同时推进,即时响应,减少用户等待时间。参考看电影同时放音乐。

    2.提高CPU利用率,提高运行效率。分多线程来执行耗时操作,记录日志,访问数据库等,同样写入五十万条数据,效率更高。

    啥时候用多线程?

    参考上面的多线程的优点,第一条对任何时候都适用。

    第二条适用于有交互或io、数据库操作、网络请求的情况。

    什么是线程安全?

    因为多线程下,多个任务同时推进,首先他们共享进程内的资源,其次,他们执行的任务可能会共享某些变量,数据,

    如果在读取和写入中间,穿插了其它的线程的一顿操作,很可能使数据出现错误的情况,

    比如常说的,并发地买火车票的情况,线程1读取剩余票数后,中间有其它线程改变了剩余票数,然后线程1再进行接下来的操作,就会出问题,

    如何解决线程安全问题?
    Java提供了两种方式:

    1.synchronized

    将代码段的变量锁定,(可以加在代码段或方法中,应该尽可能缩小锁的范围)。一个线程进入后,将锁定标记,其它线程阻塞排队,然后解锁后,顺序执行。

    为什么应该尽量缩小锁定范围呢,因为如果你在执行非互斥资源的处理,你对互斥资源的锁定,会影响其它需要互斥资源的线程继续执行,从而影响效率。

    2.lock

    lock提供了可以自定义设置的锁。

    lock的锁定和解锁需要手动调用,所以使用lock时,一般将unlock写到finally中,防止出现异常不能释放锁。

    lock还提供了trylock,使用trylock如果检查互斥资源被锁定,可以选择立即返回还是继续排队等待,并且trylock还可以设置排队等待时间。,

    所以lock比synchronization控制更加自由

    另外,Java提供一些实现了线程安全的类,比如集合中的concurrent集合,可以看一下,,,,并且可以看一下jdk实现线程安全时,有没有什么更加高明的处理方式。

    留下两个小任务,回头有时间做一下,

    1.实现一个线程安全的模拟抢票

    2.看一下jdk中的线程安全集合是如何处理线程安全的,有没有其它线程安全类和线程安全处理方式

  • 相关阅读:
    Android之旅十六 android中各种资源的使用
    XTU OJ 1207 Welcome to XTCPC (字符串签到题)
    scala并发编程原生线程Actor、Case Class下的消息传递和偏函数实战
    【云图】怎样设置支付宝里的家乐福全国连锁店地图?
    怎样在QML中使用multitouch
    软件project师周兆熊给IT学子的倾情奉献
    Linux系统下怎样配置SSH?怎样开启SSH?
    数学之路-python计算实战(4)-Lempel-Ziv压缩(2)
    Day5上午解题报告
    一份只有巨佬才能看懂的代码
  • 原文地址:https://www.cnblogs.com/lbzhu/p/10069239.html
Copyright © 2011-2022 走看看