多线程知识点

线程与进程

进程

一个程序, QQ.exe 等, 程序的一次执行过程, 是系统运行程序的基本单位, 系统运行一个程序是一个进程重创建, 运行到消亡的过程
一个进程可以包含多个线程, 至少保护一个线程

线程

程序执行的一条路径, 比进程更小的执行单位. 一个进程在执行过程中可以产生多个线程
每个线程都有自己的程序计数器, 虚拟机栈和本地方法栈

并发与并行

并发

多线程操作一个线程, 同一时间内, 多个任务都在执行, 单位时间内不一定同时执行
如 单核 CPU 快速交替

并行
多个人一起行走, 单位时间内多个任务同时执行
如 多核 CPU ,多个线程同时执行

线程状态

  1. 新生: 新创建了一个线程对象, 但是还没有调用 start() 方法
  2. 运行: Java线程中将就绪和运行中两种状态都成为运行
    a. 线程对象创建后,其他线程如main线程调用了该对象的 start() 方法, 该状态线程位于可运行线程池中, 等待被线程调度选中, 获取 CPU 的使用权, 此时属于就绪状态
    b. 就绪状态的线程在获取到 CPU 的使用权后就是运行中状态
  3. 阻塞: 线程阻塞与锁
  4. 等待: 进入该状态的线程需要等待其他线程通知
  5. 超时等待: 该状态不同于等待, 可以在指定时间后自行返回
  6. 终止: 表示该线程运行完毕

wait 与 sleep 区别

  • 来自不同的类. wait 来自 object 类方法, sleep 来自 thread 类方法
  • wait 会自动释放锁, sleep 不会释放锁
  • wait 必须在同步代码块中使用, sleep 可以在任何地方使用
  • wait 不需要捕获异常, sleep 需要捕获异常
  • **wait 方法被调用后线程不会自动苏醒.**需要其他线程调用同一个对象上的 notify() 方法或者 notifyAll() 方法唤醒线程. wait(timeout) 方法会在超时后线程自动苏醒 sleep 方法执行完后线程会自动苏醒.

什么是JUC

  • java.util.concurrent
  • java.util.concurrent.atomic 原子类
  • java.util.concurrent.locks 锁类
  • Java 1.5 提供的java.util.concurrent包,在此包中增加了并发编程中很常见的工具类

JUC中的并发工具

  • 提供了CountDownLatch, CyclicBarrier, Semaphore 等, 可以实现更丰富的多线程操作的同步结构
  • 提供了ConcurrentHashMap, 有序的 ConcurrentSkipListMap, 或者通过类似快照机制实现线程安全的动态数组 CopyOnWriteArralList等各种线程安全的容器
  • 提供了ArrayBlockingQueue, SychorousQueue 或针对特定场景的PriorityBlockingQueue等给中并发队列实现
  • 强大的Executor框架,可以创建各种不同类型的线程池,调度任务运行等

JUC 中同步器

让Java的线程彼此同步

CountDownLatch

构造方法指明计数数量, 被等待线程调用 countDown() 方法将计数器减一, 等待线程使用 await() 进行线程等待

CyclicBarrier

循环栅栏, 让一组线程等待至某个状态之后再全部同步执行, 当所有等待线程被释放后, CyclicBarrier 还可以被重复使用

Semaphore

Java 版本的信号量实现, 用于控制同时访问的线程个数, 达到限制通用资源访问的目的, 通过 acquire() 方法获取一个许可, 没有就等待, release() 方法释放一个许可

ThreadLocal

怎么解决并发安全

这是Java提供的一种保存线程私有信息的机制,因为其在整个线程生命周期内有效,所以可以方便的在一个线程关联的不同业务模块之间传递信息.
ThreadLocal 为每一个线程维护变量的副本,把共享数据的可见性范围限制在同一个线程内,其实现原理是在 ThreadLocal 类中有一个Map ,用于存储每一个线程的变量的副本,是的每一个线程在某一时间访问到的并不是同一个对象

ThreadLocal 使用要注意remove(内存泄露问题)

ThreadLocal 的实现是基于一个所谓的 ThreadLocalMap, 在这个map中,他的 **key 是一个弱引用.而value是强引用.**在没有被外部强引用的情况下,垃圾回收的时候,key会被清理掉,而value不会被清理.这样就会出现key为null的Entry.如果不做任何措施,value永远都无法被GC回收,这个时候就会产生内存泄露.
ThreadLocalMap! 这就是很多OOM的来源,所以通常会建议.应用一定要
自己负责remove
,并且不要和线程池配合,因为 worker线程往往是不会退出的.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值