JAVA并发总结
2018-07-02 14:17:42 0 举报
AI智能生成
JAVA并发总结
作者其他创作
大纲/内容
interrupted和isInterrupted都是测试当前线程是否中断,前者执行后状态清除为false,后者不清除线程状态
run方法正常结束(退出标识)、interrupt、stop方法强行终止(和suspend及resume一样过期,不推荐)都可以终止正在运行的线程
yield表示放弃当前cpu资源,不会释放锁(sleep同),wait会释放锁,并且调用wait时必须持有锁(否则IllegalMonitorStateException),notify需要等当前线程退出synchronized代码后,被唤醒的线程才会获得锁
Java中的线程有1-10的优先级,超出范围报错(IllegalArgumentException),默认5,具有继承性(A启动B,B继承A的优先级),线程优先级不可靠
setDaemon(true)将线程设置为守护线程,必须在start()之前(否则IllegalThreadStateException),Daemon中的新线程也是Daemon
synchronized加在静态方法上等同于synchronized(XX.class),加在非静态方法上等同于synchronized(this),synchronized不具有继承性(父类的sync方法在子类中重写,不具备sync特性),使用“对象监视器”同步
线程抛异常时会释放持有的锁
在A线程里执行了b.join()表示A线程等待B线程终止后才从b.join()返回。join内部使用了wait进行实现(join本身是sync方法),join可以带时间参数,表示最长等待时间
ThreadLocal实现每个线程有各自独立的副本而互不影响,重写initialValue()赋初始值。ThreadLocal对象建议设置为static。使用InheritableThreadLocal可以在子线程(A开启B,B为A的子线程)中取得父线程继承下来的值,重写childValue可以更改继承的值
ReentrantLock(可重入锁,可lock多次),tryLock调用时,如锁被持有,立即返回false,否则持有该锁并返回true
ReentrantLock构造函数传入true可以构建公平锁,即按照申请顺序依次获得锁,默认非公平
ReentrantLock可以绑定多个Condition进行精细化控制,先lock(),再调用condition的await或signal进行控制
ReentrantLock可重入锁解决了自己等待自己的死锁(持有锁后,可以调用其他需要该锁lock的方法,不会出现第二次lock时需要等待外层unlock的死锁情况)
Timer因自身缺陷(基于绝对时间,系统时钟敏感,单线程,耗时任务影响其他任务的精准性)在JDK5以后很少使用,用ScheduledThreadPoolExecutor代替
线程可以加入线程组做统一管理,new Thread时,传入线程组对象
thread.setUncaughtExceptionHandler()指定线程的默认异常处理器,Thread.setDefaultUncaughtExceptionHandler()为所有线程指定默认异常处理器,前者优先级高
Java实现读写分离用读写锁,ReentrantReadWriteLock,读与写互斥,写与写互斥,读与读不互斥
读写锁的锁降级,目的是把写锁降级为读锁。本身持有写锁,申请读锁,释放写锁,使用读锁,释放读锁。适用于写入后需要立刻使用数据的场景
ConcurrentHashMap是线程安全的HashMap,键值都不能为null,每次扩容2倍,JDK1.7的实现为锁segment(默认16),获取size时连续两次对比所有segment的count和,不相等才全部上锁。JDK1.8的ConcurrentHashMap采用了无锁CAS实现,更加高效
线程安全的非阻塞队列有ConcurrentLinkedQueue/Deque,元素不能为null,Deque有头尾两个方向。常用add,peek(取出不删除),poll(取出删除),remove,size,contains等方法
阻塞队列支持阻塞插入和阻塞获取,即队列满时,插入数据会阻塞到队列不满时进行插入,使用put和take进行操作
阻塞队列有ArrayBlockingQueue(数组,有界),LinkedBlockingQueue(链表,有界),PriorityBlockingQueue(优先级排序,无界),DelayQueue(可延迟),SynchronousQueue(put和take互相等待),LindedTransferQueue(链表,无界,transfer等待消费后返回,tryTransfer若无消费返回false),LinkedBlockingDeque(链表,双向)
Fork/Join框架,JDK1.7提供,继承RecursiveAction或RecursiveTask(父类都是ForkJoinTask,Action无返回),在conpute方法中拆分左右两个任务(new自身,传入分割后的数据),fork后join,合并结果返回,与递归类似
原子类有基本类型(AtomicBoolean,AtomicInteger,AtomicLong),数组类型(AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray),引用类型(AtomicReference,AtomicStampedReference,AtomicMarkableReference),字段类型(AtomicReferenceFieldUpdater,AtomicIntegerFieldUpdate日,AtomicLongFieldUpdater)
CountDownLatch有方法countDown(),getCount(),await()等,可以实现等待N个点完成后再继续某线程的场景
Cyclicbarrier可以设置当N个线程到达屏障时,屏障才会打开,在构造函数中传入Runnable,可以在达成条件时优先执行。可以用reset()方法重置
Semaphore信号量控制特定资源的线程数量,方法有acquire()获取资源和release()释放资源
线程间可以使用管道进行数据操作(PipedInputStream,PipedOutputStream,PipedReader,PipedWriter),in.connect(out)或out.connect(in)连接(只能连接一次,否则抛IOException: Already connected),out.write不阻塞,in.read阻塞直到read成功
Exchanger可用于线程间交换数据,echange阻塞等待另一个exchange调用,双向交换
shutdown和shutdownNow都可以关闭线程池,前者调用后不再接收新任务,等待已提交任务执行完成(包括还未执行的任务),后者尝试取消所有运行中的任务,并且不再启动尚未执行的新任务,调用任意一个方法,线程池的isShutdown()返回true
扩展ThreadPoolExecutor,重写beforeExecute和afterExecute以及terminated方法,可以对线程进行AOP操作。run中抛出Error不会调用after,before抛异常run不会执行,after也不调用,terminated在线程池关闭时调用
Thread.holdsLock(Object obj)在当前线程拥有obj的对象锁时返回true
jstack可以用来查看线程快照,-F强制生成线程快照,-m包含Java和native代码的所有堆栈信息,-l打印出锁的附加信息,jstack中的pid为16进制
Thread.sleep(0)可以触发一次系统分配时间片,让某些低优先级的线程有机会获取控制权,是平衡CPU控制权的一种操作
合理配置线程池,CPU密集型任务,线程个数应尽量少(不大于CPU核心数),IO密集型任务,应尽量多些线程,以提高CPU利用率。
0 条评论
下一页