标签:
CopyOnWrite容器即写时复制的容器。java中的容器为CopyOnWriteArrayList和CopyOnWriteArraySet。在并发场景中使用,【用于读多写少的并发场景】【http://ifeve.com/java-copy-on-write/】
ConcurrentHashMap使用的是锁分段技术,使得线程安全,还使用啥哈希,再哈希算法(高低位都参与哈希算法),高效读取操作(不使用锁)。
【http://www.infoq.com/cn/articles/ConcurrentHashMap】
ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列。【采用wait-free算法实现】【http://ifeve.com/concurrentlinkedqueue/】
Java代码: instance = new Singleton();//instance是volatile变量
汇编代码: 0x01a3de1d: movb $0x0,0x1104800(%esi);0x01a3de24: lock addl $0x0,(%esp);
锁 |
优点 |
缺点 |
适用场景 |
偏向锁 |
加锁和解锁不需要额外的消耗,和执行非同步方法比仅存在纳秒级的差距。 |
如果线程间存在锁竞争,会带来额外的锁撤销的消耗。 |
适用于只有一个线程访问同步块场景。 |
轻量级锁 |
竞争的线程不会阻塞,提高了程序的响应速度。 |
如果始终得不到锁竞争的线程使用自旋会消耗CPU。 |
追求响应时间。 同步块执行速度非常快。 |
重量级锁 |
线程竞争不使用自旋,不会消耗CPU。 |
线程阻塞,响应时间缓慢。 |
追求吞吐量。 同步块执行速度较长。 |
我们可以通过ThreadPoolExecutor来创建一个线程池。
1 |
new ThreadPoolExecutor(corePoolSize,
maximumPoolSize, |
2 |
keepAliveTime,
milliseconds,runnableTaskQueue, threadFactory,handler); |
创建一个线程池需要输入几个参数:
RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略。n AbortPolicy:直接抛出异常。
向线程池提交任务
我们可以使用execute提交的任务,但是execute方法没有返回值,所以无法判断任务知否被线程池执行成功。通过以下代码可知execute方法输入的任务是一个Runnable类的实例。
01 |
threadsPool.execute( new Runnable()
{ |
02 |
@Override |
03 |
04 |
public void run()
{ |
05 |
06 |
//
TODO Auto-generated method stub |
07 |
08 |
} |
09 |
10 |
}); |
我们也可以使用submit 方法来提交任务,它会返回一个future,那么我们可以通过这个future来判断任务是否执行成功,通过future的get方法来获取返回值,get方法会阻塞住直到任务完成,而使用get(long timeout, TimeUnit unit)方法则会阻塞一段时间后立即返回,这时有可能任务没有执行完。
01 |
try { |
02 |
03 |
Object
s = future.get(); |
04 |
05 |
} catch (InterruptedException
e) { |
06 |
07 |
//
处理中断异常 |
08 |
09 |
} catch (ExecutionException
e) { |
10 |
11 |
//
处理无法执行任务异常 |
12 |
13 |
} finally { |
14 |
15 |
//
关闭线程池 |
16 |
17 |
executor.shutdown(); |
18 |
19 |
} |
我们可以通过调用线程池的shutdown或shutdownNow方法来关闭线程池,但是它们的实现原理不同,shutdown的原理是只是将线程池的状态设置成SHUTDOWN状态,然后中断所有没有正在执行任务的线程。shutdownNow的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,所以无法响应中断的任务可能永远无法终止。shutdownNow会首先将线程池的状态设置成STOP,然后尝试停止所有的正在执行或暂停任务的线程,并返回等待执行任务的列表。
只要调用了这两个关闭方法的其中一个,isShutdown方法就会返回true。当所有的任务都已关闭后,才表示线程池关闭成功,这时调用isTerminaed方法会返回true。至于我们应该调用哪一种方法来关闭线程池,应该由提交到线程池的任务特性决定,通常调用shutdown来关闭线程池,如果任务不一定要执行完,则可以调用shutdownNow。
通过线程池提供的参数进行监控。线程池里有一些属性在监控线程池的时候可以使用
阻塞队列提供了四种处理方法:
方法\处理方式 | 抛出异常 | 返回特殊值 | 一直阻塞 | 超时退出 |
---|---|---|---|---|
插入方法 | add(e) | offer(e) | put(e) | offer(e,time,unit) |
移除方法 | remove() | poll() | take() | poll(time,unit) |
检查方法 | element() | peek() | 不可用 | 不可用 |
JDK7提供了7个阻塞队列。分别是
标签:
原文地址:http://blog.csdn.net/xiaohangblog/article/details/51280162