zoukankan      html  css  js  c++  java
  • Java并发编程小记

    1. Semaphore

      信号量是一种计数器,用来保护一个或者多个共享资源的访问。如果线程要访问一个共享资源,必须先获得信号量。若内部计数器大于0,则减1,若等于0,则线程进入休眠直至计数器大于等于0。

    Semaphore semaphore1 = new Semaphore(1); // 值为1的信号量
    Semaphore semaphore2 = new Semaphore(1, true); // 公平模式,FIFO
    semaphore1.acquire(); // 获取资源,否则阻塞,且在阻塞过程中可以被中断
    semaphore1.acquireUninterruptibly(); // 获取资源,否则阻塞,且在阻塞过程中不可被中断
    semaphore1.tryAcquire(); // 尝试获取
    semaphore1.release(); // 释放

    2. CountDownLatch

      CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。若一个线程需要等待某些操作先执行完,需调用await()方法进入休眠,当一个操作完成,则调用countDown()将内部计数器减1,若变为0时,则唤醒所有因调用await()而进入休眠的线程。

      CountDownLatch机制不是用来保护共享资源或者临界区的,它是用来同步执行多个任务的一个或者多个线程。

      CountDownLatch不能被重置。

    CountDownLatch controller = new CountDownLatch(number); // 计数器为number
    controller.countDown(); // 计数器减1
    controller.getCount(); // 获取计数器的值
    controller.await(); // 等待计数器变0

    3. CyclicBarrier

      CyclicBarrier是一个同步辅助类,它允许两个或者多个线程在某个点上进行同步。当一个线程到达指定的点后,调用await()方法休眠并等待其他的线程,当最后一个的await()方法被调用时,CyclicBarrier将唤醒所有在等待的线程然后这些线程将继续执行。

      CyclicBarrier还可以传入另一个Runnable对象作为之后运行的线程。

      CyclicBarrier可以被重置。

    CyclicBarrier barrier = new CyclicBarrier(5, task); // 需要集合5个线程,并且之后运行task
    barrier.await(); // 休眠等待
    barrier.await(long, TimeUnit); // 保持休眠直到被中断。或者内部计数器变为0,或者时间过期
    barrier.getNumberWaiting(); // 返回阻塞线程数目
    barrier.getParties(); // 返回对象同步的任务数
    barrier.reset(); // 重置对象,await()的线程抛出一个BrokenBarrierException
    barrier.isBroken(); // 判断对象是否损坏,这种状态在其中一个线程被中断抛出InterruptedException时出现

    4. Phaser

      一个辅助类,允许执行并发多阶段任务,在每一步结束时对线程进行同步。

      需要对同步操作的任务数进行初始化,但是可以动态地增加或者减少任务数。

      Phaser不会被中断响应。

    Phaser phaser = new Phaser(3); // 需要3个线程同步
    phaser.arriveAndAwaitActive(); // 等待3个线程到达此执行点
    phaser.arriveAndDeregister(); // 减少一个需要同步的线程
    phaser.onAdvance(); // 返回true则说明处于终止态
    phaser.isFinalized();    

      Phaser还提供其他改变对象的方法。

    Phaser phaser = new Phaser(3); // 需要3个线程同步
    phaser.arrive(); // 通知一个参与者已经完成了当前阶段,不应该等待其他参与者,故不会同步
    phaser.awaitAdvance(int); // 若传入参数与当前阶段一致,则当前线程休眠直到这个阶段参与者都完成;否则立即返回
    phaser.awaitAdvanceInterruptibly(int); // 若被中断抛出异常
    phaser.register(); // 注册一个新的参与者
    phaser.register(int); // 批量注册
    phaser.forceTermination(); // 强制终止 

    5. Exchanger

      一个辅助类,允许在两个线程之间定义同步点,当两个线程都到达同步点时,交换他们的数据结构。

    Exchanger<List<String>> exchanger = new Exchanger<List<String>>();
    List<String> buffer = new List<String>();
    buffer = exchanger.exchange(buffer);

    6. Executor

      分离了任务的创建和执行,只需要传递实现了Runnable接口的对象,通过执行器创建所需的线程,来负责Runnable对象的创建、实例化以及运行。其使用了线程池来提高程序的性能。

      执行期框架另外的优势是Callable接口,将获得一个实现了Future接口的对象,用其控制Callable对象的状态和结果。

    ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newCachedThreadPool(); // 创建一个缓存线程池
    executor.execute(task); // 传递实现Runnable或Callable接口的对象
    executor.getPoolSize(); // 返回执行器线程池中的实际线程数
    executor.getActiveCount(); // 返回正在执行任务的线程数
    executor.getCompletedTaskCount(); // 返回执行器已经完成的任务数
    executor.getLargestPoolSize(); // 获取曾经同时位于线程池中的最大线程数
    executor.shutdown(); // 结束
    executor.shutdownNow(); // 立即关闭执行器,返回等待执行的任务列表
    executor.isTerminated(); // 若已调研shutdown()或shutdownNow()返回true
    executor.isShutdown(); // 若已调用shutdown()返回true
    executor.awaitTermination(long, TimeUnit); // 阻塞所调用的线程,直到完成任务或者达到所指定的timeout值

      创建固定大小的Executor:

    ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(int); // 创建一个固定大小的线程池

      Future相关:

    public class FactorialCal implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
    
        }
    } // 创建实现Callable接口的实例
    Future<Integer> result = executor.submit(new FactorialCal()); // 获取结果
    Integer number = result.get(); // 获取Integer,若未完成则一直阻塞
    Integer number = result.get(long, TimeUnit); // 等待指定的时间,若未完成则返回null
    result.isDone(); // 检查任务是否完成

      其他方法:

    executor.invokdeAny(Collection<? extends Callable<T>>); // 实现任一后返回结果
    executor.invokdeAny(Collection<? extends Callable<T>>); // 实现全部后返回结果
    ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)Executor.newScheduledThreadPool(1);
    executor.schedule(new Task(), int, TimeUnit);
    ScheduledFuture<?> result = executor.scheduleAtFixedRate(new Task(), int, int, TimeUnit); // 循环任务

     

  • 相关阅读:
    luogu P1340 兽径管理
    luogu P2828 Switching on the Lights(开关灯)
    luogu P1462 通往奥格瑞玛的道路
    codevs 2596 售货员的难题
    luogu P1145 约瑟夫
    luogu P1395 会议
    luogu P1041 传染病控制
    luogu P1198 [JSOI2008]最大数
    codevs 1191 数轴染色
    [POJ1082]Calendar Game
  • 原文地址:https://www.cnblogs.com/Azurewing/p/4746588.html
Copyright © 2011-2022 走看看