并发编程交流

12
并并并并并并 bluedavy 2010-03-19

description

杭州程序员并发编程交流PPT,活动地址:http://hangzhou.koubei.com/huodong/10610100000004750

Transcript of 并发编程交流

Page 1: 并发编程交流

并发编程交流bluedavy

2010-03-19

Page 2: 并发编程交流

About PPT对于 Java 体系而言主要还是借助多线程来做并发so 下面的一切都是多线程相关点,不涉及多进程

◦资源竞争和一致性 Sun JDK 提供的支持 并发包值得学习的地方 尽可能 Nonblocking-- 例子

◦线程 线程交互 线程池 线程跟踪和问题查找 线程调度

◦Some tips

Page 3: 并发编程交流

资源竞争和一致性Sun JDK 提供的支持

◦Synchronized◦Semaphore 、 CountdownLatch◦ReentrantLock 、 Condition◦AtomicInteger 、 ConcurrentHashMap 、 ArrayBl

ockingQueue

Page 4: 并发编程交流

资源竞争和一致性并发包值得学习的地方

◦AtomicInteger 系列 CAS

◦ConcurrentHashMap 拆分锁

◦Semaphore 、 CountdownLatch 并发包中最强悍的类: AbstractQueuedSynchronizer

◦基于 LockSupport.park 和 LockSupport.unpark 来操控线程是否可被调度

◦基于队列来做等待◦看的也不是非常明白,需要懂的人分享下

Page 5: 并发编程交流

尽可能Nonblocking例子常见代码如下

private static Map<String,Connection> connections=new HashMap<String,Connection>();

public Connection get(String key) throws Exception{synchronized(connections){

if(connections.containsKey(key)){return connections.get(key);

}Connection conn=createConnection(key);connections.put(key,conn);return conn;

}}

Page 6: 并发编程交流

尽可能Nonblocking例子改造想法

◦ connections 改为 ConcurrentHashMap◦ 借助 putIfAbsent 来减少判断是否存在的 lock

private static ConcurrentHashMap<String,Connection> connections=new ConcurrentHashMap<String,Connection>();

public Connection get(String key) throws Exception{if(connections.containsKey(key)){

return connections.get(key);}Connection conn=createConnection(key);Connection realConn=connections.putIfAbsent(key,conn);if(realConn!=null){

conn.close();} return realConn;

}

Page 7: 并发编程交流

尽可能Nonblocking例子改造想法

◦能否不创建无谓的连接,想到了 FutureTaskprivate static ConcurrentHashMap<String,FutureTask<Connection>> connections=new ConcurrentHashMap<String,FutureTask<Connection>>();

public Connection get(final String key) throws Exception{if(connections.containsKey(key)){

return connections.get(key).get;}FutureTask<Connection> newTask=new FutureTask<Connection>(new

Callable<Connection>(){public Connection call() throws Exception{

return createConnection(key);}

});FutureTask<Connection> task=connections.putIfAbsent(key, newTask);if(task==null){

newTask.run();return newTask.get();

} return task.get();

}

Page 8: 并发编程交流

线程线程交互

◦wait/notify(notifyAll) 在测 kilim 一个版本时,高压力的情况下 wait/notify 貌似

有 bug , jdk 是 1.6.0_07

线程池◦ThreadPoolExecutor 做的已经不错了,但要注意合理

使用 不要使用无限制大小的线程池 最好自行实现 ThreadFactory ,最少给线程加上个前缀 当超过 coreSize 后,会扔到指定的 BlockingQueue 中,

因此要注意这个地方 ...

Page 9: 并发编程交流

线程线程跟踪和问题查找

◦jstack 、 tda 、 visualvm◦jprofiler◦pstat+jstack 直接查找耗 cpu 的线程

Page 10: 并发编程交流

线程调度最常见的问题在于必须是一个请求占据一个线程,

无论这个请求中途是否要去远程访问、文件 IO或锁等待;

Coroutine maybe 是可以考虑的方案◦轻量级线程◦基于栈分析保存相关的上下文信息:会多消耗内存◦要求整个处理过程中不能有阻塞

意味着锁、数据库访问、网络访问都得处理好◦Java 中: Scala 、 Kilim

Page 11: 并发编程交流

Some tips多线程后一定要考虑对资源的消耗,否则搞不好

性能反倒更差了◦CPU

cpu 切换是否太严重◦内存

内存消耗是否严重,在网络通信中最明显性能

◦尽可能 Non-Blocking◦拆分锁◦隔离( ReadWrite )◦CopyOnWrite ,允许读脏数据

Page 12: 并发编程交流