高并发编程是每个程序猿不可以缺少的学习。首先要对整个线程基础要有一定的理解。可以在工作中,灵活的运用。楼主比较笨。学了很多遍。至今也只是皮毛而已。望各位大神指点!—本文章是平时学习过程中的积累
-
同步和异步的区别? 同步:是一直等待回应 (一直占用资源) 异步:等待结果后 告知!(不占用资源)
2.线程的几种状态
新建 创建一个线程对象
就绪(可运行线程池中),等待cpu时间片
运行 已经获得cpu时间片 正在执行代码
堵塞 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
等待堵塞 wait(); 线程等待,放弃cpu时间片,回到就绪状态。放弃占有资源。放到等待池中。等待唤醒,唤醒之后 重新争cpu时间片
同步堵塞 线程获取同步锁,被其它线程占用 ,当前线程放在锁池中。
其他堵塞 sleep()或join() 释放cpu时间片 进入堵塞状态
死亡yield() 放弃当前cpu时间片 回到就绪状态
3.并发 是随机性串行 并行 才是两个请求同时进行
4.临界区 多个线程共享的区域 但是 只允许一个线程访问 一个线程使用其他线程等待
5.阻塞和非堵塞 线程等待 线程非等待 (线程在执行过程中暂停)
6.死锁,饥饿,活锁
死锁:多个同级别线程都占用彼此的资源都不肯释放! 形成死循环。
饥饿:一个或多个线程一直无法获取资源,一直处于等待的状态。例如 线程级别低一直让级别高的!
活锁:两个线程互相谦让 导致没有哪个线程都没有获取到资源
无饥饿状态最好的方式 就是 优先级别相同
7.线程 尽量不要用stop 方法 会造成残废数据 (可以通过状态控制) -
线程中断 可以替代stop 方法
Thread.interrupt() 中断线程
Thread.isInterrupted() 是否被中断
10.wait 等待 notify 唤醒
两个方法主要是针对object (是对象的操作) -
wait 和 sleep 区别?
都是暂停当前线程
wait 是 object的类 sleep 是thread类
wait 放弃cpu资源 放弃锁资源 sleep 是不放弃锁资源的
wait 需要 唤醒 sleep 自动唤醒
12.suspend线程挂起 , resume 继续执行
线程挂起 暂时不用这个线程去挣cpu资源 -
join 等待线程 谦让 yieId
当前线程使用join 方法后 必须等待当前线程执行完毕
当前线程使用yield 后 尽量释放自己的资源 之后 再才和其他线程挣资源
14.volatile 关键字 修饰变量使用 主要功能线程之间的可见性
15.ThreadGroup 线程组 方便管理 维护
16.Daemon 守护线程 后台线程 用户线程存在 守护线程就会存在
17.线程优先级 (字面意义)
Thread.MAX_PRIORITY
Thread.MIN_PRIORITY
18.线程安全 synchronized- public synchronized void fun() 实力方法锁 锁住整个实力对象
- public void fun(){ 同步代码块
synchronized(object)
}
3.public static synchronized void fun() 修饰静态方法 锁的是实例对象的class对象
19.重入锁 ReentrantLock 线程安全 比synchronized 更灵活 功能更多一些 重入锁可以中断线程 synchronized 不可中断
20 synchronized 基于c语言 同步锁 (非公平锁)判断标志位是否为0 加锁变为1 (其他线程等待状态 ) 执行完锁内容 标志位减一
ReentrantLock 基于 aqs 通过伪双向队列 和 cas 方式 判断变量state是否>0 实现锁
公平锁 lock 是如果变量state>0说明有锁 把当前线程变成node节点 放入队列最后位置 线程挂载状态
等unlock 释放锁的时候 唤醒下一个节点线程 公平有序
非公平锁 lock 先通过 cas 挣锁 挣锁失败后 创建节点 放入队列尾部
21.重入锁的线程中断 是对等待锁的线程进行中断
lockInterruptibly() 响应中断
isHeldByCurrentThread() 是否已经中断
22. tryLock() (设置参数)按时间去等待锁 超时等待失败
23.tryLock() (没有参数) 直接判断是否可以获取锁 如果可以 返回true 否则 false 例如:可以尽量避免死锁
24.公平锁 重入锁的另一种机制 这样保证线程都会获得资源 不会出现饥饿的状态
25.Condition 是 ReentrantLock的得力助手
await() 线程等待 释放锁 基于 重入锁的等待
signal() 线程唤醒
signalAll() 全部唤醒
26. 信号量 semaphore 可指定固定线程同时访问资源 但是非线程安全 可用于读操作
acquire() 获取一个资源
release() 释放资源
27.ReadWriteLock 读写锁 读操作是并行的 写操作是串行的 跟重入锁比 性能高很多
28.CountDownLatch 倒计时器 用于等待多个线程执行完毕后执行主线程
29. CyclicBarrier 循环栅栏 设定固定线程 每完成固定线程之后 调用其它线程(注: 是子线程)
CyclicBarrier.await() 是对每个线程的栅栏 功能是,全部线程先要完成栅栏之前的工作之后,通知另一个其它(自定义)线程。
再去完成栅栏之后的工作。 如果有多个await()方法 就是相当于分阶完成
30.LockSupport 线程堵塞 堵塞当前线程 也可以设置堵塞对象 和 wait() 不同 不需要获取对象的锁
31.线程池 作用是减少线程的创建与销毁 线程复用
1️⃣ 固定线程池 newFixedThreadPool() 使用 LinkedBlockingQueue 堵塞队列
worker set set 概念
返回一个固定的线程池 线程数超出固定 在队列中等待 当队列也满的时候 判断最大线程数 如果最大线程数也满了 就会走饱和策略 用休眠的方式来减轻线程池的压力
2️⃣ 单利线程池 newSingleThreadExecutor() 使用 LinkedBlockingQueue 堵塞队列
只创建一个线程 超出线程数 压在队列当中
3️⃣ 缓存线程 newCachedThreadPool() 使用 SynchronousQueue 堵塞队列
4️⃣ 自定义线程池
⑤
ThreadPoolExecutor 所有的线程池 是根据这个类创建的
⑥ 定时任务的 线程池 ScheduledThreadPoolExecutor 启动该线程池的两个方法
1 scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
command:执行线程
initialDelay:初始化延时
delay :前一次执行结束到下一次执行开始的间隔时间(间隔执行延 11
迟时间)
unit:计时单位
32.fork/join 分段处理 类似于MapReduce
33 JUC 工具类
1️⃣ ConcurrentHashMap 高并发线程安全的 HashMap
2️⃣ CopyOnWriteArrayList 类似ArrayList 在读多写少的场合 性能非常好 好于Vector
3️⃣ ConcurrentLinkedQueue 高效的并发队列 用链表实现。 类似于线程安全的LinkedList
4️⃣ BlockingQueue 堵塞队列,适合用于数据共享通道。
5️⃣ ConcurrentSkipListMap 跳表的实现 快速查找。
34 HashMap HashTable ConcurrentHashMap 区别
HashMap 线程不安全 1.7之前hashMap 死锁问题的要关注
HashTable 线程安全 写操作太重 锁住了整个对象 只可以一个线程
ConcurrentHashMap 1.7 实施分段锁 默认16 16个线程同时写操作 1.8之后有所调整
35 CopyOnWriteArrayList
线程安全 add方法 利用重入锁实现 每一次添加数据都是 把老数组数据复制到新数组当中之后在未尾添加新元素 之后把新数组赋值给老数组
36 ConcurrentLinkedQueue
基于cas 无锁模式
37.cas 无锁 -又称原子锁
原理就是 volatile 和 无限for 循环 实现基本原理 缺点就是很可能导致线程饥饿
38. AtomicInteger 线程安全的整形 无锁 采用 CAS
AtomicReference 基于这种基本类型的
39.锁的优化
1 减少锁持有时间 在必要的地方进行同步 减少锁的持有时间
2 减小锁粒度
3 读写锁
4 锁分离
40.ThreadLocal 线程的局部变量 (自理解为线程的单利)
大量使用该类 会导致 内存泄露
41. synchronousQueue 特殊的堵塞队列 数据交换通道
42.blockingQueue 堵塞队列 生产者/消费者
43.不变模式 final
44. Disruptor 无锁缓存框架