JAVA 多线程_笔记

1,创建线程

继承Thread类,重写run()方法;创建对象。
实现Runnable接口,作为Thread构造器参数传入。
实现Callable接口,构建FutureTask,作为Thread构造器参数传入。
线程状态:新建、就绪、运行、阻塞、等待、死亡

2,控制线程

start();就绪
join();加入到当前线程
interrupt();中断线程
setDeamon();设为守护线程
sleep()/yield();暂停线程,建议使用sleep(),保证可移植性。
setPriority();设置优先级,建议使用Thread常量设置,保证可移植性。
Future方法
cancel();取消任务
get();获取任务结果,阻塞调用线程
isDone()/isCancelled();是否完成/取消

3,线程同步

synchronize
synchronize(obj){…};同步代码块,同步监视器为obj
synchronize修饰的实例方法,为同步方法;同步监视器为this
同步锁(lock)
类中提供final修饰的成员变量lock,充作同步监视器;在需要加锁/解锁的地方调用lock()/unLock()。
Lock实现类ReentrantLock、ReadWriteLock实现类ReentrantReadWriteLock。
ReentrantReadWriteLock锁模式:Reading、Writing、ReadingOptimistic。
方法:
lock()/tryLock()
unLock()

4,协调线程运行

释放同步监视器条件
同步方法/代码块结束(执行结束、break/return跳出、抛出异常)
调用同步监视器wait()方法
传统线程协调运行
通过调用同步监视器方法实现。
wait();令当前线程进入阻塞状态,并释放同步监视器
notify()/notifyAll();唤醒同步监视器为调用对象的线程,当前线程释放同步监视器的锁定后,才可执行唤醒线程
使用Condition协调线程运行
协调同步锁式线程同步方式。
Condition condition = lock.newCondition();//获取绑定在lock上的condition实例
await();阻塞当前线程,解锁
singal()/singalAll();唤醒等待lock的阻塞线程
使用BlockingQueue协调线程运行
BlockingQueue为Queue子接口,主要用作线程同步工具。实现类:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、DelayQueue。
put() ;存,队列满时阻塞当前线程
take();取,队列空时阻塞当前线程

5,线程组

对一批线程进行分类管理;通过构造器创建。
countActive();活动线程数
getName();线程组名
interrupt();中断线程组中所有线程
setDeamon()/isDeamon();设置为守护线程组/是否守护线程组
setMaxPriority();设置线程组内线程最高优先级
uncaughtException();处理线程组内线程抛出的异常

6,线程异常处理

线程异常处理
线程抛出异常时,JVM自动检查是否有对应(静态、实例)的Thread.UncaughtExceptionHandler对象,如有则调用其uncaughtException()方法来处理异常。
static void setDefaultUncaughtExceptionHandler();设置线程类的默认异常处理器
void setUncaughtExceptionHandler();设置线程对象的异常处理器
线程组异常处理
ThreadGroup实现了Thread.UncaughtExceptionHandler接口;作为组内线程的默认异常处理器。
异常处理:
1,如有,则调用线程实例、线程类的UncaughtExceptionHandler处理异常。
2,调用所属线程组的UncaughtExceptionHandler处理异常,如线程组有父线程组,则调用其父线程组的异常处理对象。如异常为ThreadDeath的对象,不做任何处理;否则打印异常跟踪栈到System.err,并结束线程。
注意
使用catch捕获异常时,异常不会向上传播;使用异常处理器处理异常后,异常依旧会传播给上一级调用者。

7,线程池

降低因新建线程的开销;避免过多的并发线程导致JVM崩溃。
普通线程池
Executors,工厂类,产生线程池

  • newCachedThreadPool();返回ExecutorService
  • newFixedThreadPool();
  • newSingleThreadExecutor();
  • newScheduledThreadPool();返回ScheduledExecutorService
  • newSingleThreadScheduledExecutor();
  • newWorkStealingPool();返回后台线程池ExecutorService

ExecutorService,普通线程池

  • submit();提交任务
  • shutdown();关闭线程池

ScheduleExecutorService,可指定延时或周期性执行的线程池

  • schedule();提交任务

ThreadPoolExecutor
建议通过ThreadPoolExecutor构造器初始化线程组,意义更明确。
ForkJoinPool
通过构造器获取实例对象。
submit()/invoke();执行ForkJoinTask

8,线程相关类

ThreadLocal
线程局部变量,用于成员变量。
ThreadLocal tlStr = new ThreadLocal<>();
get()/set();获取/设置
remove();删除当前线程的值
线程安全集合
通过Collections工具类synchronized*()方法,包装集合。
java.util.concurrent包下的线程安全集合;Concurrent类写入性能好,CopyOnWrite类读取性能好。

9,原子类

https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/Multithread/Atomic.md
解决并发读写问题,性能优于synchronized锁。可原子更新基本变量、对象、对象指定属性。
原理:CAS(compare and set)、volatile、native方法
核心类:Atomic*类,getter/setter方法。

10,AQS

https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/Multithread/AQS.md
AbstractQueuedSynchronizer,用于构建锁和同步器的框架。
原理
资源空闲,则当前线程锁定资源,开始工作;资源被占用,线程进入阻塞、唤醒时锁分配机制。
共享方式:独占(公平锁-按队列顺序、非公平锁-无视队列顺序)、共享。
AQS使用模板模式,继承AbstractQueuedSynchronizer;重写方法,state=0时释放资源。
Semaphore
计数信号量,用于管理一组资源,基于AQS共享模式实现;通过boolean数组辅助判定。
Semaphore s = new Semaphore(num);新建,默认非公平
aquire()/release();获取许可/释放许可,加在资源前后。
CountDownLatch
闭锁,同步工具类,允许一个或多个线程A一直等待,直到其他线程B执行完毕再执行。阻塞线程A。A启动B,类似join。
CountDownLatch c = new CountDownLatch(num);
countDown()/await();计数器为0,唤醒所有调用await()方法的线程。
CyclicBarrier
循环栅栏,让一组线程A到达一个屏障时被阻塞,直到最后一个线程A到达屏障。阻塞线程A。
CyclicBarrier c = new CyclicBarrier(num);
await();阻塞,自动重置
Lock
ReentrantLock、ReentrantReadWriteLock。
lock()/tryLock(),unlock();
Condition c = lock.newCondition();
await(),signal()/signalAll();释放资源等待,释放资源唤醒;
signal()方法在同步代码块执行完毕后释放资源

11,多线程的三个特性

共享资源问题,通过对特性的管理,让结果可预期。
线程特性:可见性、原子性、有序性
非同步代码,必须注意原子性;否则可能报错。
http://www.cnblogs.com/dafanjoy/p/10020225.html
java内存模型:主内存、工作内存、执行引擎;线程对变量的操作只能在工作内存中进行,线程间值传递只能通过主内存。
内存间操作,原子性操作;两个原子性操作叠加非原子性操作:

  • lock/unlock;锁/解锁主存变量
  • read、load;读主存到工作内存
  • store、write;工作内存写到主存
  • use/assign;工作内存值赋给执行引擎、执行引擎值赋给工作内存

JVM会尽力保证内存的可见性;volatile、锁保证线程可见性。
Happen Before规则,防重排影响:

  • 程序次序规则;同一线程内按代码顺序
  • 锁定规则;unlock先于lock
  • volatile变量规则;写操作先于后面的读操作
  • 传递规则;A先于B,B先于C,则A先于C。
  • 线程规则;包括线程启动规则、线程中断规则、线程终结规则;start()最前,终结检测最后,interrupt()先于代码的中断检测。
  • 对象终结规则;对象初始化先于finalize()。

锁:一种协调多线程运行的机制。协调线程运行,让结果可预期。
锁的特性:排他性、阻塞性、可重入性(同步方法间互调,判定加锁线程和当前线程)。
死锁:相互持有对方需要的资源锁,导致全部等待。
高并发锁
https://www.cnblogs.com/bhlsheji/p/4681194.html
考察锁:相互排斥性、无死锁、无饥饿
Amdahl定律:加速比S=1/(1-p+p/n);p可并行部分,n处理器数。故为提高性能,应减小互斥锁粒度、少用锁。
并发级别:阻塞、无障碍、无锁、无等待;非阻塞基于CAS
java中的锁
https://blog.csdn.net/zqz_zqz/article/details/70233767
锁类型:乐观锁(写时加锁,基于CAS,比较版本号)、悲观锁
线程阻塞代价:java线程映射到操作系统原生线程;阻塞、唤醒线程时,需要在用户态、内核态之间切换(上下文切换),会消耗大量资源。
java对象数据结构:对象头(markword对象自身运行时数据、klass类型指针、[数组长度])、实例数据、[对齐填充]。HotSpot要求对象大小必须是8字节的整数倍,优先以实例数据填充,而后用对齐填充。
markword:java对象数据结构的一部分,存储对象自身运行时数据;最后2bit为锁状态标志位。
java中的锁:轻量级锁、偏向锁(有竞争则释放偏向锁)、自旋锁、重量级锁(互斥)。重量级锁为悲观锁,其他为乐观锁。
轻量级锁、偏向锁、自旋锁;由jvm实现,非阻塞。偏向锁需手动打开,自旋锁默认打开。
锁状态:无锁、偏向锁、轻量级锁、重量级锁。
锁优化
减少锁时间,减少同步代码块。
锁粒度控制,细化粗化;减少锁对象冲突、进入临界区次数
消除缓存行的伪共享;jdk8开启-XX:-RestrictContended,通过padding隔离变量。
读写分离、读写锁、cas
使用并发类,如ConcurrentHashMap等。
锁粗化、不可能冲突的代码使用不同的锁。

12,分布式锁

任何互斥的都能作锁。
CAP理论:一致性Consistency、可用性Availiability、分区容错性Partition tolerance。
一般采用AP,即高可用、最终一致。
分布式为多进程;多线程共享堆内存,故可用内存作标记存储位置。多进程需将标记存储在所有进程都能看到的地方。
分布式锁控制进程共享变量、资源的访问。
需要怎样的分布式锁
1,可保证集群中,同一方法在同一时间只被一台机器上的一个线程执行。排他性。
2,可重入、[阻塞、公平]
3,获取锁、释放锁高可用,性能高
4,超时,防死锁
基于数据库的分布式锁
乐观锁:基于表唯一索引,基于表字段版本号
悲观锁:基于数据库排他锁(查询时for update)
基于Redis的分布式锁
setnx()、expire();直接设置过期时间,setnx后宕机可能异常
setnx()、get()、getset()、del();通过设置值判定是否过期
基于ZooKeeper的分布式锁
zookeeper基础知识:

  1. zk一般由多个节点构成(单数);对其修改数据,其内部将所有节点修改后才提供查询。
  2. zk数据以目录树形式存在,称为znode;znode可增加子节点,可存储数据(一般不超过1M)
  3. 子节点类型:序列化节点(节点名自增)、临时节点(客户端失联时自动删除)、普通节点。
  4. watch机制,client可以监控节点事件。

zk锁:

  • 创建临时有序节点,判定节点名是否最小;是则获取锁,否则监听前一个节点。
  • 若创建临时节点,因无序,节点删除时会导致所有线程争锁,产生羊群效应。监听前序节点。

注意事项
1,分布式锁的开销
2,加锁粒度
3,加锁方式

13,分布式事务

事务:数据库管理系统执行过程中的一个逻辑单位;ACID特性,只支持单库。能保证高可靠,不能保证高可用(硬盘故障)。
事务隔离级别:Read-uncommitted、Read-committed、Repeatable-read、Serializable
分布式事务:事务的参与者,支持事务的服务器、资源服务器、事务管理器,分别位于不同分布式系统的不同节点上。协助跨异类的事务识别资源的事务。
BASE:基本可用Basic Availiable、软状态Soft state、最终一致Eventually consistent

  • 基本可用:允许损失部分功能,保证核心功能。
  • 软状态 :允许系统中存在中间状态,不影响可用性。可能不一致。
  • 最终一致:经过一段时间后,所有节点数据将达到一致。网络延迟后的一致性。

幂等性:多次调用和首次调用的结果一致。
解决方案:

  1. 结合MQ的最终一致性
  2. TCC方案(trying-confirming-canceling)
  3. 最大努力通知。
  4. XA,两段提交

14,分布式session

1,ip-服务器绑定
2,tomcat集群共享session
3,重写Request,外部存储session
4,数据库存储session
分布式、多线程
多线程为单进程上的多线程,共享内存。分布式为多进程上的多线程,无共享区。
多线程特性:可见性、原子性、有序性。分布式可参照理解。
锁的实质:协调多线程,让结果可预期。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值