同步容器,如HashTable,提供独占访问。html
并发容器,ConcurrentHashMap,有着更好的并发性能,可是不能独占访问。java
--putIfAbsentspring
同步工具:安全
闭锁:CountDownLatch多线程
FutureTask并发
Semaphoreapp
栅栏:Barrier框架
Executor框架:jvm
Executors.newFixedThreadPool()函数
Executors.newCachedThreadPool()
ExecutorService接口,获取Future运行结果。
CompletionService接口,ExecutorCompletionService,并行运行,并等待结果。
...等
java并无提供某种抢占式的机制来取消操做或者终结内存,它提供了一种协做式的中断机制来实现取消操做。
当有界队列被填满后,饱和策略开始发挥做用。
--终止策略,抛弃任务,并抛出未受检异常
--调用者运行策略。
--对策略进行修改。
线程工厂ThreadFactory。自定义线程工厂,为新线程指定UncaughtExceptionHandler、定制Thread类用于记录信息等。
定制和扩展ThreadPoolExcutor。
--定制:自定义线程池大小、存活时间、线程工厂、饱和策略等。
--扩展:beforeExecute(),afterExecute和terminate()。能够添加计时、日志、统计和信息收集功能。
stream并行处理,CompletableFuture
关闭和取消:
1. 如何好的关闭一个任务?
任务和线程是独立的,也就是说线程运行任务,可是关闭任务并不意味着退出线程。
a)stop()函数----@Deprecated。已经弃用,由于强制退出线程,会形成不少没法预料的错误。
* @deprecated This method is inherently unsafe. Stopping a thread with * Thread.stop causes it to unlock all of the monitors that it * has locked (as a natural consequence of the unchecked * <code>ThreadDeath</code> exception propagating up the stack). If * any of the objects previously protected by these monitors were in * an inconsistent state, the damaged objects become visible to * other threads, potentially resulting in arbitrary behavior. Many * uses of <code>stop</code> should be replaced by code that simply * modifies some variable to indicate that the target thread should * stop running. The target thread should check this variable * regularly, and return from its run method in an orderly fashion * if the variable indicates that it is to stop running. If the * target thread waits for long periods (on a condition variable, * for example), the <code>interrupt</code> method should be used to * interrupt the wait.
b)使用共享变量。
在遇到阻塞等待时,就失去效果了。
https://stackoverflow.com/questions/10961714/how-to-properly-stop-the-thread-in-java
c)使用中断。
须要任务代码的支持,只能解决抛出InterruptedException异常的阻塞,若是任务代码不支持或者如IO阻塞等,也失去了效果。
d)处理不可中断的阻塞。
本身实现Thread的继承类,重写interrupt()函数,自行关闭阻塞的函数,如关闭IO链接等。
http://www.cnblogs.com/simbachen/p/4009562.html
总结:若是写多线程程序时,须要考虑提早结束的状况,那么要有任务代码的支持。任务代码必需要考虑如何响应中断,如何提早关闭,而不是只考虑计算逻辑等待线程被强制结束。
由于强制结束会有不少不肯定因素,好比可能部分修改了对象中的变量,标志位没有恢复,IO未关闭等。
ps. 对继承的认识有了提升,之前以为继承只是为了继承一些属性和行为,如今发现能够作的事情不少,能够扩展行为,能够改变行为。
处理非正常的线程终止:捕获RuntimeException。
未捕获异常的处理:继承UncaughtExceptionHandler,有点像spring中的ExceptionHandler;ThreadGroup。
钩子:经过Runtime.getRuntime().addShutdownHook()注册。当jvm关闭的时候,会执行系统中已经设置的全部经过方法addShutdownHook添加的钩子,当系统执行完这些钩子后,jvm才会关闭。因此这些钩子能够在jvm关闭的时候进行内存清理、对象销毁等操做。
同一个JVM最好只使用一个关闭钩子,而不是每一个服务都使用一个不一样的关闭钩子,使用多个关闭钩子可能会出现当前这个钩子所要依赖的服务可能已经被另一个关闭钩子关闭了。为了不这种状况,建议关闭操做在单个线程中串行执行,从而避免了再关闭操做之间出现竞态条件或者死锁等问题。
http://www.cnblogs.com/zhuawang/p/4523503.html
守护线程,非守护线程:
考虑多线程的代价。
1. 死锁
2. 性能。上下文切换,内存同步,阻塞。
3. 锁的竞争。锁分段,锁分解。
测试多线程。
1. 贴近真实场景
2. 线程执行的不肯定性。
3. 使用 回调函数 或者 扩展类 获取信息。
4. 考虑垃圾回收、动态编译/编译优化的影响。
ReentrantLock、ReadWriteLock和synchronized内置锁
1. ReentrantLock实现Lock接口,更丰富,提供定时的锁等待、可中断的锁等待、公平性选择。可是是互斥的。
2. synchronized编写简单,出代码块时自动unlock。
3. 读写锁ReadWriteLock。可选读优先/写优先,多个读一个写。
java更底层的同步机制
synchronized和wait/notify/notifyAll结合使用,注意“过早唤醒”和“信号丢失”状况。
Condition,更细分等待线程。
悲观锁--独占性,lock
乐观锁--CAS(会有ABA问题)
安全的发布/不安全的发布:缺乏happens-before关系时,会出现重排序现象。