多线程总结

部分知识点总结来自: 多线程学习

进程与线程

进程: 每个进程都有独立的代码和数据空间(进程上下文, 进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)
     多进程是指操作系统能同时运行多个任务(程序)
线程: 同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是CPU调度的最小单位)
     多线程是指在同一程序中有多个顺序流在执行

多线程实现方式

1.继承Thread类(单继承局限)   
2.实现Runnable接口  
3.实现Callable 接口(可返回执行结果)

线程状态

线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

常用方法

sleep(long millis)   当前线程暂停millis 毫秒
join()  暂停当前线程, 直至调用join()的线程执行完毕
yield()  本质是把当前线程重新置入可运行队列中
isAlive() 判断一个线程是否存活
activeCount() 程序中活跃的线程数
currentThread() 获取当前执行线程
isDaemon() 一个线程是否为守护线程
setPriority() 设置一个线程的优先级
setDaemon() 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否依赖于主线程结束而结束)
interrupt()  如果线程处于sleep, wait, join 等状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常;
             如果线程处于I/O阻塞状态,将会抛出ClosedByInterruptException(IOException的子类)异常
             否则将直接标记 interrupt 状态   

Synchronized 同步锁 (获取锁以及释放锁都是Java虚拟机帮助用户完成的)
锁作用域:
  1. 对象锁, 此时该对象不能同时访问类中其他Synchronized方法
  2. 类锁, 此时该类的所有对象不能同时访问类中其他Synchronized方法
应用方式:
  1. 普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
  2. 静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁
  3. 同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
ReentrantLock 排他锁 (需要用户手动获取锁和释放锁)
公平锁: 先到达的线程优先执行;     非公平锁:  由系统调度
ReentrantLock(boolean fair)  true 设置为公平锁, 默认为false
lock()  获取锁, 获取不到就一直阻塞, 获取锁之后才可响应中断信号
unlock()  释放锁
tryLock() 尝试获取锁, 立即返回
tryLock(long time, TimeUnit unit)  获取到锁, 则返回, 否则在指定时间去获取锁, 超时未获取到, 返回false
lockInterruptibly() 未获取到锁, 也可响应中断
isHeldByCurrentThread() 当前线程是否获取到该锁    
ReentrantReadWriteLock 读写锁
同一时刻可以运行多个读线程或者一个写线程, 大大提高了并发性和吞吐量
特性:  1. 公平性选择: 支持非公平(默认)和公平的锁获取方式, 吞吐量还是非公平优于公平
      2. 重进入: 该锁支持重进入,读线程在获取了读锁之后, 能够再次获取读锁; 而写线程在获取了写锁之后能够再次获取写锁,同时也可以获取读锁
      3. 锁降级: 将写锁降级为读锁(先获取写锁,再获取读锁,再释放写锁,最后释放读锁)
      4. 条件变量: 写入锁支持Condition的使用, 读取锁获取Condition时抛出UnsupportedOperationException异常
关于锁降级: 在两个锁的语句块之间, 有可能线程的交替执行, 造成线程安全问题, 锁降级解决了这个问题, 并且提升了性能
问题示例: 假设线程A修改了数据, 释放了写锁, 这个时候线程B获得了写锁, 修改了数据, 然后也释放了写锁, 线程A读取数据的时候, 如果线程B修改了线程A修改的数据, 则线程A无法读取到线程A自己修改的数据
Synchronized 与 ReentrantLock 对比
相同: 都为可重入锁:同一个线程每进入一次,锁的计数器都自增1,要等到锁的计数器下降为0时才能释放锁
不同: 1. Synchronized是依赖于JVM实现的(自动获取,释放锁), 为Java关键字; 而ReentrantLock是JDK实现的(需手动获取, 释放锁)
     2. Synchronized为非公平锁, ReentrantLock可指定公平锁或非公平锁
     3. Synchronized不可中断, ReentrantLock可响应中断
     4. Synchronized不能唤醒指定线程, ReentrantLock可唤醒指定线程
     5. Synchronized发生异常时, 会自动释放锁, ReentrantLock必须手动释放锁
     6. ReentrantLock提供多个方法获取锁的信息
多线程辅助类及其部分API
CountDownLatch(int count)  一个同步辅助类
当参数count等于0时, 可唤醒多个调用了await()的阻塞线程
适用场景: 用来将一个任务分为n个独立的部分, 等这些部分都完成后继续接下来的任务
 await()  阻塞当前线程, 直至count = 0
 await(long timeout, TimeUnit unit)  阻塞指定时间后, 自动唤醒
 countDown()  count--
 getCount() 获取count值


Semaphore(int permits) 一个计数信号量
只颁发permits数量的许可, 只有获取到许可的线程, 才可执行, 否则阻塞等待
适用场景: 用于资源数量固定, 线程获取完资源后, 其他线程需等待其他线程归还资源后, 再执行的情况
 acquire()  获取1个许可, 无可用许可则阻塞
 acquire(int permits)  获取指定数量许可
 release()  归还1个许可
 release(int permits)  归还指定数量许可


CyclicBarrier(int parties)  一个同步辅助类
可以协同多个线程,让多个线程在这个屏障前等待,直到所有线程都达到了这个屏障时,再一起继续执行后面的动作
使用场景: 多个线程有固定的多步需要执行,线程间互相等待,当都执行完了,再一起执行下一步
   await()  阻塞当前线程, 直至 parties个线程到达 await()的位置
   await(long timeout, TimeUnit unit)  阻塞指定时间后, 自动唤醒
   getNumberWaiting()  获取当前等待线程数
   reset()  重置


Exchanger  两个线程之间的双向交换
第一个先拿出数据的线程会一直等待第二个线程,直到第二个线程拿着数据到来时才能彼此交换对应数据
   V exchange(V x)  交换并返回交换后的数据
   V exchange(V x, long timeout, TimeUnit unit)  交换并返回交换后的数据, 超时抛出异常
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值