当前位置: 首页 > news >正文

兰州官网seo分析/快排seo软件

兰州官网seo分析,快排seo软件,网页设计实训总结100字,三级分销系统想想一下这样一个场景,有多个人需要过河,河上有一条船,船要等待满10个人才过河,过完河后每个人又各自行动。 这里的人相当于线程,注意这里,每个线程运行到一半的时候,它就要等待一个条件&#x…

想想一下这样一个场景,有多个人需要过河,河上有一条船,船要等待满10个人才过河,过完河后每个人又各自行动。

这里的人相当于线程,注意这里,每个线程运行到一半的时候,它就要等待一个条件,即船满过河的条件,之后每个线程才能继续执行。使用CyclicBarrier就可以实现这个需求

一. CyclicBarrier介绍

CyclicBarrier表示循环屏障,它内部有个屏障数count,当调用await方法就会减少一个屏障,并让当前线程等待。当屏障数count减到0的时候,表示条件已满足,所有等待的线程应该被唤醒,并且重置屏障数count,这样就可以继续使用了。

要让线程条件等待,就想到了Condition对象,它能够实现当不满足条件时,调用await方法让当前线程等待。满足条件时调用signal或signalAll方法,唤醒等待的线程。

二. 重要成员属性

   /*** Generation一代的意思。* CyclicBarrier是可以循环使用的,用它来标志本代和下一代。* broken:表示本代是不是损坏了。标志有线程发生了中断,或者异常,就是任务没有完成。*/private static class Generation { boolean broken = false; } /** 用它来实现独占锁 */ private final ReentrantLock lock = new ReentrantLock(); /** 用它来实现多个线程之间相互等待通知,就是满足某些条件之后,线程才能执行,否则就等待 */ private final Condition trip = lock.newCondition(); /** 初始化时屏障数量 */ private final int parties; /* 当条件满足(即屏障数量为0)之后,会回调这个Runnable */ private final Runnable barrierCommand; /** 当前代 */ private Generation generation = new Generation(); // 剩余的屏障数量count。当count==0时,表示条件都满足了 private int count; 

重要属性:

  1. count: 当前剩余的屏障数量。用它来判断条件是否满足
  2. generation: 当前代。
  3. lock: 独占锁,用它来保证修改成员变量时,多线程并发安全问题。
  4. trip: Condition对象,用它来实现不满足条件时,线程等待,满足条件时,唤醒等待线程。

三. await方法

    /*** 减少屏障数count,* 如果屏障数count等于0了,条件满足,当前返回,并唤醒所有等待线程。* 如果屏障数不为0,那么当前线程等待。*/public int await() throws InterruptedException, BrokenBarrierException { try { return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen } } /** * 与await()方法作用一样,只不过添加了超时设置。 * */ public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException { return dowait(true, unit.toNanos(timeout)); } 

这个方法很重要,我们就是调用这个方法,让当前线程等待着某个条件的满足的。它内部是通过调用dowait方法实现的。

四. dowait方法

   private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException { final ReentrantLock lock = this.lock; // 使用lock锁,保证同一时间只有一个线程修改这些共享变量(这里就是这些成员属性) lock.lock(); try { final Generation g = generation; // 表示本代已经被损坏,抛出BrokenBarrierException异常 if (g.broken) throw new BrokenBarrierException(); // 如果当前线程中断标志位true,发生了中断,表示本代CyclicBarrier也损坏了, // 所以调用breakBarrier方法,并抛出InterruptedException异常 if (Thread.interrupted()) { breakBarrier(); throw new InterruptedException(); } // 每次调用dowait方法,表示满足了一次条件,所以count自减 int index = --count; if (index == 0) { // 表示条件都满足了,开始放行 boolean ranAction = false; try { final Runnable command = barrierCommand; if (command != null) command.run(); ranAction = true; // 开始下一代 nextGeneration(); return 0; } finally { // 如果ranAction为false,说明command.run()方法产生异常,也表示本代损坏 if (!ranAction) breakBarrier(); } } // 如果index不等于0,表示条件没有满足,所以就要让当前线程等待。 for (;;) { try { // timed表示是否允许设置超时时间。 if (!timed) trip.await(); else if (nanos > 0L) nanos = trip.awaitNanos(nanos); } catch (InterruptedException ie) { if (g == generation && ! g.broken) { breakBarrier(); throw ie; } else { Thread.currentThread().interrupt(); } } /** * 执行到这里说明,当前线程被唤醒了,并获取了锁。 * 有三种方式,都可以让线程执行到这里: * 1. 有个线程被中断或者发生异常,调用breakBarrier方法,会让等待的线程执行到这里 * 2. 所有条件都满足,调用nextGeneration方法之后,会让等待的线程执行到这里 * 3. 如果等待的线程设置了超时时间,如果被超时唤醒,那么也会执行到这里 */ if (g.broken) throw new BrokenBarrierException(); if (g != generation) return index; if (timed && nanos <= 0L) { breakBarrier(); throw new TimeoutException(); } } } finally { lock.unlock(); } } 

这个方法是CyclicBarrier中最重要的方法。它的作用就是将当前屏障数count减一,然后判断条件是否满足(即count == 0),满足就唤醒所有等待的线程,方法返回,如果不满足,就让当前线程等待。

正常情况下,流程就是如此,但是如果运行的线程发生异常,或者等待的线程被中断唤醒了,这个就会出现问题,直接调用breakBarrier方法,表示CyclicBarrier功能失败。

    /***  这个方法只在本代条件都满足(count==0)调用。*  1.唤醒所有等待的线程*  2.重置count值。*  3.创建新的Generation变量,表示下一代*/private void nextGeneration() { // signal completion of last generation trip.signalAll(); // set up next generation count = parties; generation = new Generation(); } /** * 当有一个线程发生中断或者异常的时候调用。 * 1.将本代的broken设置为true * 2.重置count值。 * 3.唤醒所有等待的线程 */ private void breakBarrier() { generation.broken = true; count = parties; trip.signalAll(); } 

nextGeneration和breakBarrier都有唤醒线程和重置屏障数count的功能,不同点就是nextGeneration设置新的generation,而breakBarrier方法会将当前generation的broken设置为true,表示被破坏掉了。

五.重要示例

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierTest { public static void newThread(String name, CyclicBarrier barrier) { new Thread(new Runnable() { @Override public void run() { try { System.out.println("线程"+Thread.currentThread().getName()+"等待船满过河"); barrier.await(); System.out.println("线程"+Thread.currentThread().getName()+"过完河, 各自行动"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }, name).start(); } public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(10, new Runnable() { @Override public void run() { System.out.println("\n在线程"+Thread.currentThread().getName()+"中 船过河了\n"); } }); for (int i = 1; i <= 10; i++) { newThread("t"+i, barrier); } } } 

运行结果:

线程t1等待船满过河
线程t2等待船满过河
线程t3等待船满过河
线程t4等待船满过河
线程t5等待船满过河
线程t6等待船满过河
线程t7等待船满过河
线程t8等待船满过河
线程t9等待船满过河
线程t10等待船满过河在线程t10中 船过河了线程t10过完河, 各自行动
线程t1过完河, 各自行动
线程t2过完河, 各自行动
线程t3过完河, 各自行动
线程t4过完河, 各自行动
线程t5过完河, 各自行动
线程t6过完河, 各自行动
线程t7过完河, 各自行动
线程t8过完河, 各自行动
线程t9过完河, 各自行动

 

转载于:https://www.cnblogs.com/igoodful/p/9705312.html

http://www.jmfq.cn/news/5053177.html

相关文章:

  • 做网站购买服务器/网络营销工作内容
  • 金华市金东区建设局网站/百度写一篇文章多少钱
  • 竞价单页网站制作/seo论坛站长交流
  • 山东省济南市莱芜区/seo和sem的区别
  • 中国建设银行的网站./百度一下官网搜索引擎
  • 可以做商城网站的公司/新冠疫情最新数据
  • 法治建设网站模块名称/百度文库网页版
  • 网站建设制作经验足/百度手机app
  • 国企单位网站建设方案/seo推广外包
  • 商务网站建设哪家好/永久观看不收费的直播
  • 电脑建网站软件/搜外滴滴友链
  • 网站模板好/公众号推广费用一般多少
  • 绵阳专门做网站的公司有哪些/北京seo排名优化网站
  • 网站建设模板怎么设计/seo优化顾问服务
  • 仿站源码/营销方案推广
  • 宁波seo服务快速推广/免费seo教程
  • asp网站连接数据库/郑州网站
  • 怎么用域名建网站/百度推广用户注册
  • 密云做网站/写一篇软文多少钱
  • asp源码下载网站/搜索网站排名优化
  • 禅城网站建设公司/竞价销售是什么意思
  • 网页版面布局/seo优化的作用
  • 东莞网站设计与网站制作/如何去除痘痘有效果
  • 福田瑞沃大金刚/seo学习
  • 海门网站建设制作/网站推广的基本方法是
  • 网站收缩栏/百度热搜榜历史
  • 用开源吗做的网站可以用吗/网络营销的六个特点
  • 做网站不给源码程序/seo服务公司上海
  • 贵州网站建设公司有哪些/百度seo公司兴田德润
  • web网页开发基础/宁波seo怎么做引流推广