java 并发编程实战 第二天
2015-02-15 23:08
411 查看
第四章
对象的组合
这章书看得我有点云里雾里的感觉.可能是没有好好的去实战或者什么的,更多的都是停留在看.
这本书说到现在有两点是要值得注意的.1.不变条件.2,后验条件.如果违背了这两个.就可能出现线程不安全的问题.
要保证线程安全
可以通过加锁,加内置锁
监听器模式,将对象还有内置锁保护起来.主要的优点是简单性.
线程安全委托,通过多个线程安全类来组合获得较好的线程安全(AtomicLong/加内置锁)
第五章.基础构建模块
同步容器类
还是那个问题.如果看到"先判断在修改"就可能出现不安全的问题.
在容器迭代的时候不希望加锁.
ConcurrentModificationException的出现:
当他们发现在迭代过程容器中被修改的时候就会报这个错.
解决办法:因此使用Iterator遍历集合时,不要改动被迭代的对象,可以使用Iterator本身的方法remove()来删除对象,Iterator.remove()方法会在删除当前迭代对象的同时维护modCount和expectedModCount值的一致性。
同步工具类:
闭锁(Latch):相当于一个内置锁,会直接阻塞着,await();等待,countDown(),减少一,当减为零的时候就是代表空闲.
FutureTask:这个有点像回调函数的感觉,跟Callable搭配着一起用的.
信号量(Semaphore):可以用作互斥体,类似(AtomicXXX);
栅栏(barrier):主要的作用就是等待所有的来亲了才动手.
对象的组合
这章书看得我有点云里雾里的感觉.可能是没有好好的去实战或者什么的,更多的都是停留在看.
这本书说到现在有两点是要值得注意的.1.不变条件.2,后验条件.如果违背了这两个.就可能出现线程不安全的问题.
要保证线程安全
可以通过加锁,加内置锁
监听器模式,将对象还有内置锁保护起来.主要的优点是简单性.
线程安全委托,通过多个线程安全类来组合获得较好的线程安全(AtomicLong/加内置锁)
第五章.基础构建模块
同步容器类
还是那个问题.如果看到"先判断在修改"就可能出现不安全的问题.
//类似这种的可能会出现大问题.可能两个线程都拿到了size()为1但是有一个继续操作了.剩下那个就报错了.
publicstaticvoiddeleteLast(Vectorlist){
intlastIndex=list.size()-1;
list.remove(lastIndex);
}
//最简单最粗暴的改进方法就是直接加锁.
publicstaticvoiddeleteLast(Vectorlist){
//但是这样做会引来性能上的大问题.这个方法就直接被阻塞掉了.
synchronized(list){
intlastIndex=list.size()-1;
list.remove(lastIndex);
}
}
在容器迭代的时候不希望加锁.
ConcurrentModificationException的出现:
当他们发现在迭代过程容器中被修改的时候就会报这个错.
//这是AbstractList上面的方法.
//modCount是修改上面数字的次数
//expectedModCount是期望值,如果期望值不跟实际相等就会报错.
privatevoidcheckForComodification(){
if(l.modCount!=expectedModCount)
thrownewConcurrentModificationException();
}
解决办法:因此使用Iterator遍历集合时,不要改动被迭代的对象,可以使用Iterator本身的方法remove()来删除对象,Iterator.remove()方法会在删除当前迭代对象的同时维护modCount和expectedModCount值的一致性。
同步工具类:
闭锁(Latch):相当于一个内置锁,会直接阻塞着,await();等待,countDown(),减少一,当减为零的时候就是代表空闲.
publiclongtimeTasks(intnThreads,finalRunnabletask)throwsInterruptedException{
//它使用两个闭锁,分别是“起始门(startGate)”和“结束门(endGate)
finalCountDownLatchstartGate=newCountDownLatch(1);
finalCountDownLatchendGate=newCountDownLatch(nThreads);
for(inti=0;i<nThreads;i++){
Threadt=newThread(){
publicvoidrun(){
try{
startGate.await();
task.run();
}catch(InterruptedExceptione){//ignored
}finally{
endGate.countDown();
}
}
};
t.start();
}
longstart=System.nanoTime();
startGate.countDown();
endGate.await();
longend=System.nanoTime();
returnend-start;
}
FutureTask:这个有点像回调函数的感觉,跟Callable搭配着一起用的.
publicstaticvoidfuture(){
ExecutorServiceexecutor=Executors.newFixedThreadPool(10);
FutureTask<String>futureTask=newFutureTask<String>(newCallable<String>(){
publicStringcall(){
//真正的任务在这里执行,这里的返回值类型为String,可以为任意类型
return"simple";
}
});
executor.execute(futureTask);try{
//取得结果,同时设置超时执行时间为5秒。同样可以用future.get(),不设置执行超时时间取得结果
Stringresult=futureTask.get(5000,TimeUnit.MILLISECONDS);
//业务处理……
System.out.println(result);
}catch(InterruptedExceptione){
Thread.currentThread().interrupt();
}catch(ExecutionExceptione){
//skip
}catch(TimeoutExceptione){
//skip
}finally{
executor.shutdown();
}
}
信号量(Semaphore):可以用作互斥体,类似(AtomicXXX);
栅栏(barrier):主要的作用就是等待所有的来亲了才动手.
相关文章推荐
- Java 并发编程实战学习笔记——路径查找类型并行任务的终止
- java 并发编程实战 第五天 ThreadPoolExecutor 源码分析
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介
- 【Java并发编程实战】—–“J.U.C”:Condition
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析
- Java 并发编程实战学习笔记——CountDownLatch的使用
- 【Java并发编程实战】-----线程基本概念
- 【Java并发编程实战】—–“J.U.C”:ReentrantLock之一简介
- 【Java并发编程实战】—–synchronized
- 【Java并发编程实战】-----“J.U.C”:Condition
- java 并发编程实战 第一天
- java并发编程实战手册第三章同步辅助类Phaser
- java并发编程实战之线程安全性
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之二lock方法分析
- Java 并发编程实战学习笔记——寻找可强化的并行性
- java 并发编程实战 第四天
- java并发编程实战手册第二章2.8与死锁的演示
- java 并发编程实战第三章同步辅助类CyclicBarrier解析
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析
- 【Java并发编程实战】—–“J.U.C”:ReentrantLock之二lock方法分析