并发与多线程——线程安全

基本概念

并发:在某个时间段内,多任务交替处理的能力。

并行:同时处理多任务的能力。

并发与并行的目标:尽肯能快的执行完所有任务

并发特点:

  1. 并发程序之间有相互制约的关系。

    (1)直接制约:一个程序需要另一个程序的结果。

    (2)间接制约:程序间竞争共享资源。

处理器、缓冲区、磁盘IO等

  1. 并发程序的执行过程是断断续续的。

这与CPU的调度算法有关

  1. 并发数设置合理并且CPU拥有足够处理能力是,并发会提高程序的效率。

(1)在极端情况下,比如单核CPU,在单核的条件下,并发一般比串行效率要低,只要消耗在上下文切换–记忆现场和恢复现场等。
(2)防止阻塞:单核CPU下使用并发,主要是考虑防止阻塞。单核CPU使用单线程,如调用接口迟迟没有返回,那你的线程就一直阻塞,直到接口返回为止,但使用多线程就能防止这个问题,就算一个接口调用阻塞了,但并不影响其他线程的执行。

线程安全

  1. 线程状态

在这里插入图片描述

(1) new,新建状态,线程被创建且未启动的状态。

​ 创建线程的三种方式:

​ a. extends Thread

​ b. implement Runnable

​ c. implement Callable

相比第一种,推荐第二种,因为继承不符合里氏代换原则;Runnable与Callable的不同点:
第一,call()方法具有返回值,前两种方式都有缺陷,即在任务执行完成后无法直接获取执行结果,需要借助共享变量获取。
第二,call()可以抛出异常。Runnable只能通过setDefaultUncaughtExceptionHandler()的方式才能在主线程中捕获到子线程的异常。

(2) runnable,就绪状态,调用start()之后运行之前的状态。

start()不能多次调用。

(3) running,运行状态,run()正在执行的状态。

时间、异常、锁、调度等会使线程退出running

(4)blocked,阻塞状态,以下情况会进入阻塞状态:

a.同步阻塞:锁被其他线程占用。

b.主动阻塞:调用Thread的某些方法,主动让出CPU执行权,如sleep()、join()等。

c.等待阻塞:wait()。

sleep与wait的相同点:sleep与wait都会使CPU让出执行权,不同点:sleep不会释放线程所占有的锁,wait会释放线程所占有的锁

(5)dead,终止状态,run()执行结束或者异常退出后的状态,此状态不可逆转。

  1. 线程安全

    (1)数据单线程内可见。

线程局部变量

(2)只读对象。

条件:使用final修饰类,避免继承;使用private final修饰属性避免修改;没有任何的更新方法;返回值不能为可变对象的引用;

(3)线程安全类。

(4)同步与锁机制。

  1. 并发包

    (1)线程同步类。

主要代表为CyclicBarrier、CountDownLatch、Semaphore等,逐步淘汰wait和notify同步方式。

(2)并发集合类。

主要代表ConcurrentHashMap(不断优化,从分段锁到CAS)、CopyOnWriteArrayList、BlockingQueue等。

(3)线程管理类。

线程池ThreadPoolExecutor

(4)锁相关类。

Lock,主要代表为ReentrantLock

《Easy Coding》读书笔记

发布了6 篇原创文章 · 获赞 25 · 访问量 2506

猜你喜欢

转载自blog.csdn.net/qq_36011946/article/details/83796911