java并发编程实践(4)
来源:互联网 发布:搜索合作网络关闭 编辑:程序博客网 时间:2024/06/03 18:53
1、扩展ThreadPoolExecutor该类中的beforeExcute(任务执行前被调用)、afterExecute(任务执行后被调用,无论是否正常被执行,抛出异常也会被执行)、terminated(线程池完成关闭时执行)方法可在子类中被改写;
2、锁顺序死锁:多个线程以不同的顺序获得多个对象的锁时发生死锁的现象;eg:
/*线程1:*/synchronized(obj1){ synchronized(obj2){ /*语句块*/ }}/*线程2:*/synchronized(obj2){ synchronized(obj1){ /*语句块*/ }}
此时如果线程1获得obj1的锁而线程2 获得obj2的锁,那么会形成死锁;
如果以相同的顺序获取锁,死锁问题就能得到解决:
/*线程1:*/synchronized(obj1){ synchronized(obj2){ /*语句块*/ }}/*线程2:*/synchronized(obj1){ synchronized(obj2){ /*语句块*/ }}
3、开放调用
如果调用某个方法时不需要持有锁,这种方式称作开放调用;
/*协作对象之间产生死锁**/class A { private B b = new B(); public synchronized void a(){ /*需要同步的重要代码*/ b.b(); } public synchronized void c(){ }}class B{ private A a = new A(); public synchronized b(){ } pubic synchronized d(){ /*需要同步的重要代码*/ a.c(); }}
如果对象之间存在协作,当线程1调用class B的d()方法时,此时线程1可能获得两个锁,如果线程2调用class A的a()方法,此时线程2也有可能获得两个锁,当且仅当线程1没获得锁时这个可能性才成立,若线程1获得class B的锁而线程2获得class A的锁,那么此时会发生死锁现象;
采用开放调用的方式可以解决这个问题:
/*开放调用**/class A { private B b = new B(); public void a(){ synchronized(this){ /*需要同步的重要代码*/ } b.b(); } public synchronized void c(){ }}class B{ private A a = new A(); public synchronized b(){ } pubic d(){ synchronized(this){ /*需要同步的重要代码*/ } a.c(); }}
此时调用外部方法时,线程已经没有持有锁,因此不会发生死锁的现象。
4、减小锁的竞争
1)、减小锁的范围(”快进快出”),比如如果采用synchronized关键字修饰整个方法,资源就被线程独占,若方法体执行时间长,影响整个程序的性能,若果我们将方法中需要同步的代码用synchronized同步,则可能能减少线程对当前资源的持有时间;
2)、减小锁的粒度
ArrayBlockingQueue不支持同时读写,其底层实现使用了ReextranLock锁,类似synchronized方法会被调用线程独占,而LinkedBlockingQueue减小了锁的粒度,其实现对读操作和写操作分别用了不同的锁,所以可以同时读写操作
public class LinkedBlockingQueue<T>{ Lock write = new ReextranceLock(); Lock read= new ReextranceLock(); /*读操作*/ public T take(){ write.lock(); /**其他代码省略**/ } /*写操作*/ public void put(T e){ read.lock(); /**其他代码省略**/ }}
3)、锁分段
将锁使用在一组独立的对象上,如ConcurrentHashMap;其使用的是散列数据结构,每个桶位独占一把锁,因此可以支持多线程并发访问;其伪代码如下:
public class ConncurrentHashMapTest{ private static final INI_LOCK = 16; private final Node[] bucket; private final Object[] lock; private static Node{ /*省略*/ } public Object get(Object key){ int i = hash(key); synchronized(lock[i]){ /*省略*/ } }}
- java并发编程实践(4)
- 《Java并发编程实践》
- JAVA并发编程实践
- 《Java并发编程实践》
- Java 并发编程实践
- Java并发编程实践
- java并发编程实践
- Java并发编程实践
- java并发编程实践学习(4)构建块
- java并发编程实践 笔记(1)
- Java并发编程实践 笔记(节选)
- Java并发编程实践读书笔记(一)
- Java并发编程实践读书笔记(二)
- Java并发编程实践读书笔记(三)
- java多线程(2):并发编程实践
- Java并发编程实践笔记(一)
- java并发编程实践(公司讲座)
- 《JAVA并发编程实践》读书笔记(一)
- 数据恢复
- spring_day4_08-ssh框架整合总结
- MachineLearning
- 字符集and校对集
- c++中new与delete的用法总结
- java并发编程实践(4)
- spring_day4_09-ssh框架整合其他方式(没有hibernate核心配置文件)
- Unity零基础入门
- 002Add-Two-Numbers
- Nutz 设计模式应用 --- 静态工厂方法
- spring_day4_10-spring分模块开发
- 创建Django项目时失败的问题
- 《一个Android工程的从零开始》阶段总结与修改3-BaseActivity上
- 服务器请求状态值和状态码