Java并发

本文介绍了Java中并发编程的关键技术和工具类,包括volatile关键字、同步容器、并发容器如ConcurrentHashMap及CopyOnWriteList、阻塞队列、Executor框架、闭锁CountDownLatch、信号量Semaphore、栅栏Barrier等,同时探讨了如何利用这些工具进行高效的任务执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对象的共享

  • volatile

同步容器类

Collections.sychronizedXXX();

  • 迭代时修改会引发ConcurrentModificationException异常,因为modCount有变化

并发容器

  1. ConcurrentHashMap:使用一种粒度更细的加锁机制来实现更大程度的共享,称为分段锁;其迭代器具有弱一致性,而不是快速失败。
  2. CopyOnWriteList:每次修改时都会创建并重新发布一个新的容器副本,从而实现可变性,迭代操作远远多于修改操作时使用。
  3. 阻塞队列和生产者-消费者模式()
    • Executor任务执行框架中就体现了这种模式
    • BlockingQueue的三种实现:LinkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue、SynchronousBlockingQueue
    • 双端队列:Deque、BlockingDeque

同步工具类

闭锁

  1. CountDownLatch
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();
                    }
                }
            }
        }
    }
    long start = System.nanoTime();
    startGate.countDown();
    emdGate.await();
    long end = System.nanoTime();
    return end-start;
}
  1. FutureTask
    实现了Future语义,通过Callable来实现,有三种状态:等待运行、正在运行、运行完成。Future.get的行为取决于任务的状态,如果任务完成,get会立即返回结果,否则阻塞到任务进入完成状态。FutureTask在Executor框架中表示异步任务。
FutureTask<Product> future = new FutureTask<Product>(new Cllable<Product>){
    public Product call() throws DataLoadException {
        return load();
    }
}
return future.get;
  1. 信号量Semaphore
    Semaphore可以用于实现资源池,例如数据库连接池。
    Semaphore sem = new Semaphore();
    sem.acquire();
    sem.release();
  1. 栅栏Barrier
    闭锁用于等待事件,栅栏用于等待线程,CyclicBarrier可以使一定数量的参与方反复的在栅栏位置汇集。
CylicBarrier barrier = new CylicBarrier(count, new Runnable() {
    public void run() {
        mainBoard.commitNewValues();
    }
});
barrier.await();

另一种形式的栅栏式Exchange,是一种两方栅栏

任务执行

Executor框架

Executor exec = new Executors.newFixedThreadPool(n);
exec.execute();
  1. 静态工厂方法
    • newFixedThreadPool:固定长度
    • newCachedThreadPool:可缓存,规模不存在任何限制
    • newSingleThreadExecutor:单线程,确保工作顺序执行
    • newScheduledThreadPool:固定长度,以延时或定时的方式来执行任务,类似于Timer
  2. 生命周期
    • shutdown:不接受新的任务,等待已经提交的任务执行完成(包括未开始执行的任务)
    • shutdownNow:直接关闭所有任务
    • awaitTermination:等待ExecutorService到达终止状态
    • isTerminated:查看是否终止

寻找可利用的并行性

  1. 携带结果的任务Callable与Future
    Future的get中如果抛出了异常,会封装为ExecutionException并重新抛出,可以通过getCause获取被包装的异常。ExecutorService的submit方法将发挥一个Future
  2. CompletionService:Exector与BlockingQueue
    CompletionService将Executor和BlockingQueue的功能融合在一起,可以将Callable任务提交执行,然后使用take、poll等方法获取结果,结果封装为Future。ExecutorCompletionService实现了CompletionService,并将计算部分委托给一个Executor。
    ExecutorCompletionService在构造函数中创建一个BlockingQueue来保存计算完成的结果,当计算完成时,调用Future-Task中的done方法。提交任务时,首先将任务包装为一个QueueingFuture(FutureTask的一个子类),然后改写子类的done方法,并将结果放入BlockingQueue。

取消与关闭

任务取消

  1. 使用volatile类型的域来保存取消状态
  2. 中断是实现取消的最合理方式
  3. 3.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值