线程

你掌握线程吗?他是Java并发的基础元素,理解、操作和诊断线程你都熟悉吗?下面有几个问题我们一起来看一下吧:

  • 线程到底是什么
  • 线程和进程有什么区别?
  • 有什么因素可能影响到线程的状态?
  • 线程部分API使用建议

是什么?

在操作系统中,线程是系统调度的最小单元,他有自己的私有空间。一个进程可以包含多个线程,进程的私有空间可以被线程门共享。

线程和进程有什么区别?

在Android中,一个进程是一个独立的运行环境,可以看成是一个应用程序或应用(一个程序可以有多个进程),不同的进程使用不同的内存空间
在操作系统中,线程是系统调度的最小单元,是进程中执行的一个任务
一个进程可以有多个线程,每条线程并行执行不同的任务
进程中的不同线程共享一片相同的内存空间(文件描述符、虚拟地址空间等),线程拥有独立的空间存储本地数据(栈Stack、寄存器Register、本地存储ThreadLocal等)

有什么因素可能影响到线程的状态?

  • 自身方法:start,join等待线程结束,yield告诉调度器要主动让出CPU
  • 基类Object的destroy/notify/notifyAll方法,本质是Monitor获取和释放的能力,是基本的线程间通信方式。
  • 并发类库中的工具,as CountDownLatch.await()让当前线程进入等待状态,可看作线程间通信的Signal


    thread.png

线程部分API

守护线程

不会影响程序退出,UI Thread和默认创建的新Thread是非守护的。在需要一个长期驻留且不影响应用退出的服务程序时可以使用。thread.isDaemon = true

Spurious wakeup

虚假唤醒,在没有任何线程广播或者发出信号的情况下线程被唤醒。产生诡异的并发问题,推荐编写方式

while(isTrue){doSth()}  而不是if(isTrue){doSth()}
自旋锁

Thread.onSpinWait()是一种针对短期等待的性能优化技术,只是对JVM的一种暗示,没有行为上的保证

ThreadLocal

在线程生命周期内有效,可以保存线程私有信息,需要慎用。
数据存储于线程相关的ThreadLocalMap中,内部条目是弱引用。当key为null时变成废弃条目,value需要回收。通常弱引用会和引用队列配合清理机制使用,但ThreadLocal是个意外
所以废弃条目回收需要 显示触发,或者等待线程结束 才能回收相应ThreadLocalMap,这也是大部分OOM的来源,所以一定要自己负责remove并不和线程池配合

你可能感兴趣的:(线程)