JAVA并发编程学习笔记------基础构建模块

时间:2023-12-18 09:29:26

一、并发容器:
ConcurrentHashMap:
1、分段锁机制: 任意数量的读取线程可以并发的访问map,执行读取操作的线程和执行写入操作的线程可以并发的访问Map,并且一定数量的写入线程可以并发的修改Map。
2、无需再迭代过程中对容器加锁;
3、ConcurrentHashMap无法实现对Map加锁已提供独占访问,在HashMap及SynchrogazedMap中,获得Map的锁能防止其他线程访问这个Map;
4、大多数情况下,用ConcurrentHashMap代替同步Map能进一步提高代码的可伸缩性,只有当应用程序需要加锁Map以进行独占访问时,才应该放弃使用ConcurrentHashMap。

CopyOnWriteArrayList:
1、用于代替同步List,迭代期间不需要对容器进行加锁或复制;
2、 容器的线程安全性在于: 只要正确的发布一个事实不可变的对象,那么在访问该对象时就不需要进一步的同步,在每次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。
3、仅当迭代操作远远多于修改操作时,才应该使用“写入时复制”容器。

二、同步工具类:
1. 闭锁:
(1)延迟线程的进度直到其到达终止状态,可用来确保某些活动直到其他活动都完成后才继续执行;
(2)实现:CountDownLatch

public class TestHarness {
public long timeTasks(int nThreads, final Runnable task) throws InterruptedException {
final CountDownLatch startGate = new CountDownLatch(1);
final CountDownLatch endGate = new CountDownLatch(nThreads);
for(int i=0;i<nThreads;i++){
Thread t = new Thread(){
public void run(){
try{
startGate.await();
try {
task.run();
}finally {
endGate.countDown();
}
}catch (InterruptedException ignored){ }
}
};
t.start();
}
long start = System.nanoTime();
startGate.countDown();
endGate.await();
long end = System.nanoTime();
return end-start;
}
}

  

2、栅栏(Barrier)
(1)栅栏类似于闭锁,它能阻塞一组线程直到某个事件发生,它与闭锁的关键区别在于:所有线程必须同时到达栅栏,才能继续执行。闭锁用于等待事件,而栅栏用于等待线程。闭锁一旦打开将不会再关闭,栅栏打开后还可以重置以供下次使用。

(2)实现方式: CyclicBarrier(摘自http://www.itzhai.com/the-introduction-and-use-of-cyclicbarrier.html)

public class CyclicBarrierTest {
public static void main(String[] args) throws IOException, InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(3); ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new Thread(new Runner(barrier, "1号选手")));
executor.submit(new Thread(new Runner(barrier, "2号选手")));
executor.submit(new Thread(new Runner(barrier, "3号选手"))); executor.shutdown();
} static class Runner implements Runnable{
private CyclicBarrier barrier; private String name; public Runner(CyclicBarrier barrier, String name) {
super();
this.barrier = barrier;
this.name = name;
} @Override
public void run() {
try {
Thread.sleep(1000 * (new Random()).nextInt(8));
System.out.println(name + " 准备好了...");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(name + " 起跑!");
}
}
}