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

北京住房和城乡建设委员会网站证件查询系统百度怎么优化关键词排名

北京住房和城乡建设委员会网站证件查询系统,百度怎么优化关键词排名,滚动网站模版,seo做的比较牛的公司阻塞队列一 阻塞队列1.1.阻塞队列概念1.2.阻塞队列API案例1.2.1. ArrayBlockingQueue1.2.1.1.抛出异常1.2.1.2.返回布尔1.2.1.3.阻塞1.2.1.4.超时1.2.2.SynchronousQueue二 阻塞队列应用---生产者消费者2.1.传统模式案例代码结果案例问题---防止虚假唤醒2.2.⽣产者消费者防⽌虚…

阻塞队列

  • 一 阻塞队列
    • 1.1.阻塞队列概念
    • 1.2.阻塞队列API案例
      • 1.2.1. ArrayBlockingQueue
        • 1.2.1.1.抛出异常
        • 1.2.1.2.返回布尔
        • 1.2.1.3.阻塞
        • 1.2.1.4.超时
      • 1.2.2.SynchronousQueue
  • 二 阻塞队列应用---生产者消费者
    • 2.1.传统模式
      • 案例代码
      • 结果
      • 案例问题---防止虚假唤醒
    • 2.2.⽣产者消费者防⽌虚假唤醒
      • 2.2.1 新版⽣产者消费者写法 ReentrantLock.Condition
        • 案例代码
      • 2.2.2精准通知顺序访问
        • 案例代码
    • 2.3.Synchronized和Lock的区别
    • 2.4. 阻塞队列模式⽣产者消费者
      • 案例代码

在这里插入图片描述

一 阻塞队列

1.1.阻塞队列概念

概念:

  • 在多线程领域:所谓阻塞,在某些情况下会挂起线程(即阻塞),⼀旦条件满⾜,被挂起的线程⼜ 会⾃动被唤醒。
  • 阻塞队列 是⼀个队列,在数据结构中起的作⽤如下图:
    在这里插入图片描述

当队列是空的,从队列中获取(Take)元素的操作将会被阻塞
当队列是满的,从队列中添加(Put)元素的操作将会被阻塞
试图中空的队列中获取元素的线程将会被阻塞,直到其他线程往空的队列插⼊新的元素
试图向已满的队列中添加新元素的线程将会被阻塞,直到其他线程从队列中移除⼀个或多个元素 或者完全清空,使队列变得空闲起来后并后续新增

好处:阻塞队列不⽤⼿动控制什么时候该被阻塞,什么时候该被唤醒,简化了操作。
体系: Collection→ Queue→ BlockingQueue→七个阻塞队列实现类。
在这里插入图片描述
在这里插入图片描述
粗体标记的三个⽤得⽐较多,许多消息中间件底层就是⽤它们实现的。
需要注意的是 LinkedBlockingQueue 虽然是有界的,但有个巨坑,其默认⼤⼩是 Integer.MAX_VALUE ,⾼达21亿,⼀般情况下内存早爆了(在线程池的 ThreadPoolExecutor 有体现)。
API:

抛出异常是指: 当队列满时,再次插⼊会抛出异常;
返回布尔是指:当队列满时,再次插⼊会返回false;
阻塞是指:当队列满时,再次插⼊会被阻塞,直到队列取出⼀个元素,才能插⼊。
超时是指:当⼀个时限过后,才会插⼊或者取出。

在这里插入图片描述

1.2.阻塞队列API案例

1.2.1. ArrayBlockingQueue

1.2.1.1.抛出异常

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码

public class BlockingQueueDemo {public static void main(String[] args) throws InterruptedException {//定义容量为3的阻塞队列BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);System.out.println(blockingQueue.add("a"));System.out.println(blockingQueue.add("b"));System.out.println(blockingQueue.add("c"));System.out.println(blockingQueue.add("e"));System.out.println(blockingQueue.element());System.out.println(blockingQueue.remove());System.out.println(blockingQueue.remove());System.out.println(blockingQueue.remove());System.out.println(blockingQueue.remove());}

结果分析

  1. 当添加四个元素时抛出IllegalStateException: Queue full

在这里插入图片描述

  1. 当取出四个元素时抛出NoSuchElementException

在这里插入图片描述

1.2.1.2.返回布尔

在这里插入图片描述
代码

  public static void main(String[] args) throws InterruptedException {//定义容量为3的阻塞队列BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);System.out.println(blockingQueue.offer("a"));System.out.println(blockingQueue.offer("b"));System.out.println(blockingQueue.offer("c"));System.out.println(blockingQueue.offer("e"));System.out.println(blockingQueue.peek());System.out.println(blockingQueue.poll());System.out.println(blockingQueue.poll());System.out.println(blockingQueue.poll());System.out.println(blockingQueue.poll());}

结果

在这里插入图片描述

1.2.1.3.阻塞

代码

 public static void main(String[] args) throws InterruptedException {//定义容量为3的阻塞队列BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);blockingQueue.put("a");blockingQueue.put("b");blockingQueue.put("c");blockingQueue.put("d");System.out.println(blockingQueue.take());System.out.println(blockingQueue.take());System.out.println(blockingQueue.take());System.out.println(blockingQueue.take());}

结果

  1. 存储是容量已满
    在这里插入图片描述
  2. 取得时候队列为空也会阻塞
    在这里插入图片描述

1.2.1.4.超时

代码

  public static void main(String[] args) throws InterruptedException {//定义容量为3的阻塞队列BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);System.out.println(blockingQueue.offer("a",2L, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a",2L, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a",2L, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a",2L, TimeUnit.SECONDS));}

结果
在这里插入图片描述

1.2.2.SynchronousQueue

队列只有⼀个元素,如果想插⼊多个,阻塞到队列元素取出后,才能插⼊,只能有⼀个“坑位”,⽤⼀个
插⼀个,详⻅SynchronousQueueDemo。
代码


public class SynchronousQueueDemo {public static void main(String[] args) {BlockingQueue<String> blockingQueue=new SynchronousQueue<String>();new Thread(()->{try {System.out.println(Thread.currentThread().getName()+"\t put 1");blockingQueue.put("1");System.out.println(Thread.currentThread().getName()+"\t put 2");blockingQueue.put("2");System.out.println(Thread.currentThread().getName()+"\t put 3");blockingQueue.put("3");} catch (InterruptedException e) {e.printStackTrace();}},"AAA").start();new Thread(()->{try {try{ TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }System.out.println(Thread.currentThread().getName()+"\t take "+blockingQueue.take());try{ TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }System.out.println(Thread.currentThread().getName()+"\t take "+blockingQueue.take());try{ TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }System.out.println(Thread.currentThread().getName()+"\t take"+blockingQueue.take());} catch (Exception e) {e.printStackTrace();}},"BBB").start();}
}

结果
在这里插入图片描述

二 阻塞队列应用—生产者消费者

2.1.传统模式

传统模式使⽤ Synchronized来进⾏操作。

案例代码

/*** 题目:现在两个线程,可以操作初始值为零的一个变量,* 实现一个线程对该变量加1,一个线程对该变量-1,* 实现交替,来10轮,变量初始值为0.* 1.高内聚低耦合前提下,线程操作资源类* 2.判断/干活/通知* 3.防止虚假唤醒(判断只能用while,不能用if)* 知识小总结:多线程编程套路+while判断+新版写法*/
public class ProdConsumerDemo {public static void main(String[] args) {Aircondition aircondition = new Aircondition();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {aircondition.increment();} catch (Exception e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 1; i <= 5; i++) {try {aircondition.decrement();} catch (Exception e) {e.printStackTrace();}}}, "B").start();}
}
class Aircondition {private int number = 0;//⽼版写法public synchronized void increment() throws Exception {//1.判断if (number != 0) {this.wait();}//2.⼲活number++;System.out.println(Thread.currentThread().getName() + "\t" + number);//3通知this.notifyAll();}public synchronized void decrement() throws Exception {//1.判断if (number == 0) {this.wait();}//2.⼲活number--;System.out.println(Thread.currentThread().getName() + "\t" + number);//3通知this.notifyAll();}
}

结果

在这里插入图片描述

案例问题—防止虚假唤醒

上述我们只用了一个线程作为生产者,一个线程作为消费者,我们用多个来进行测试。防止虚假唤醒(判断只能用while,不能用if)

while循环与if判断
while是循环语句,当满足条件时执行语句,执行完循环以后再回来判断是否满足,满足继续执行,然后继续判断,不满足直接执行下面的语句
if是判断语句,满足条件就行,执行完以后继续执行下面的语句,不会再回来判断执行。

A线程生产包子,B线程消费包子,C线程生产包子,D线程消费包子
在这里插入图片描述

public class ProdConsumerDemo {public static void main(String[] args) {Aircondition aircondition = new Aircondition();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {aircondition.increment();} catch (Exception e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 1; i <= 5; i++) {try {aircondition.decrement();} catch (Exception e) {e.printStackTrace();}}}, "B").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {aircondition.increment();} catch (Exception e) {e.printStackTrace();}}}, "C").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {aircondition.decrement();} catch (Exception e) {e.printStackTrace();}}}, "D").start();}
}

Aircondition

class Aircondition {private int number = 0;//⽼版写法public synchronized void increment() throws Exception {//1.判断while (number != 0) {this.wait();}//2.⼲活number++;System.out.println(Thread.currentThread().getName() + "\t" + number);//3通知this.notifyAll();}public synchronized void decrement() throws Exception {//1.判断while (number == 0) {this.wait();}//2.⼲活number--;System.out.println(Thread.currentThread().getName() + "\t" + number);//3通知this.notifyAll();}
}

2.2.⽣产者消费者防⽌虚假唤醒

2.2.1 新版⽣产者消费者写法 ReentrantLock.Condition

Synchronized用在多线程中太重了,在高并发场景使用lock方式更加合适。所以我们使用lock来加锁和解锁。对应的等待和唤醒线程方法也换成java.util.concurrent.locks下面的newCondition方法。
在这里插入图片描述

案例代码

class Aircondition{private int number = 0;private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();//新版写法public void increment() throws Exception{lock.lock();try{//1.判断while (number != 0){condition.await();}//2.干活number++;System.out.println(Thread.currentThread().getName()+"\t"+number);//3通知condition.signalAll();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void decrement() throws Exception{lock.lock();try{//1.判断while (number == 0){condition.await();}//2.干活number--;System.out.println(Thread.currentThread().getName()+"\t"+number);//3通知condition.signalAll();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}
}public class ProdConsumerDemo {public static void main(String[] args) {Aircondition aircondition = new Aircondition();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {aircondition.increment();} catch (Exception e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 1; i <= 5; i++) {try {aircondition.decrement();} catch (Exception e) {e.printStackTrace();}}}, "B").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {aircondition.increment();} catch (Exception e) {e.printStackTrace();}}}, "C").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {aircondition.decrement();} catch (Exception e) {e.printStackTrace();}}}, "D").start();}
}

2.2.2精准通知顺序访问

现在有这样一个需求:

备注:多线程之间按顺序调用,实现A->B->C
三个线程启动,要求如下:
A打印5次,B打印10次,C打印15次
接着
A打印5次,B打印10次,C打印15次
来10轮
1.高内聚低耦合前提下,线程操作资源类
2.判断/干活/通知
3.多线程交互中,防止虚假唤醒(判断只能用while,不能用if)
4.标志位

在这里插入图片描述

案例代码

class ShareData{private int number = 1;//A:1,B:2,C:3private Lock lock = new ReentrantLock();private Condition c1 = lock.newCondition();private Condition c2 = lock.newCondition();private Condition c3 = lock.newCondition();public void printc1(){lock.lock();try {//1.判断while (number != 1){c1.await();}//2.干活for (int i = 1; i <= 5; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}//3.通知number = 2;//通知第2个c2.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void printc2(){lock.lock();try {//1.判断while (number != 2){c2.await();}//2.干活for (int i = 1; i <= 10; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}//3.通知number = 3;//如何通知第3个c3.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void printc3(){lock.lock();try {//1.判断while (number != 3){c3.await();}//2.干活for (int i = 1; i <= 15; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}//3.通知number = 1;//如何通知第1个c1.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}
}/*** 备注:多线程之间按顺序调用,实现A->B->C* 三个线程启动,要求如下:* A打印5次,B打印10次,C打印15次* 接着* A打印5次,B打印10次,C打印15次* 来10轮*      1.高内聚低耦合前提下,线程操作资源类*      2.判断/干活/通知*      3.多线程交互中,防止虚假唤醒(判断只能用while,不能用if)*      4.标志位*/
public class ConditionDemo {public static void main(String[] args) {ShareData shareData = new ShareData();new Thread(()->{for (int i = 1; i <= 10; i++) {shareData.printc1();}},"A").start();new Thread(()->{for (int i = 1; i <= 10; i++) {shareData.printc2();}},"B").start();new Thread(()->{for (int i = 1; i <= 10; i++) {shareData.printc3();}},"C").start();}
}

结果
在这里插入图片描述
结果分析
在这里插入图片描述

2.3.Synchronized和Lock的区别

synchronized关键字和 java.util.concurrent.locks.Lock都能加锁,两者有什么区别呢?

  1. 原始构成: sync是JVM层⾯的,底层通过monitorenter和monitorexit来实现的。 Lock是
    JDK API层⾯的。( sync⼀个enter会有两个exit,⼀个是正常退出,⼀个是异常退出)
  2. 使⽤⽅法: sync不需要⼿动释放锁,⽽ Lock需要⼿动释放。
  3. 是否可中断: sync不可中断,除⾮抛出异常或者正常运⾏完成。 Lock是可中断的,通过调
    ⽤ interrupt()⽅法。
  4. 是否为公平锁: sync只能是⾮公平锁,⽽ Lock既能是公平锁,⼜能是⾮公平锁。
  5. 绑定多个条件: sync不能,只能随机唤醒。⽽ Lock可以通过 Condition来绑定多个条件,精确唤醒。

2.4. 阻塞队列模式⽣产者消费者

为什么需要BlockingQueue?

好处是我们不需要关⼼什么时候需要阻塞线程,什么时候需要唤醒线程,因为这⼀切BlockingQueue都
给你⼀⼿包办好了,使⽤阻塞队列 后就不需要⼿动加锁了。
在Concurrent包发布以前,在多线程环境下,我们每个程序员都必须去⾃⼰控制这些细节,尤其还要兼
顾效率和线程安全,⽽这会给我们的程序带来不⼩的复杂度。

在这里插入图片描述

案例代码

public class ProdConsBlockQueueDemo {public static void main(String[] args) {MyResource myResource = new MyResource(new ArrayBlockingQueue<>(5));new Thread(() -> {System.out.println(Thread.currentThread().getName() + "\t生产线程启动");try {myResource.myProd();} catch (Exception e) {e.printStackTrace();}}, "prod").start();new Thread(() -> {System.out.println(Thread.currentThread().getName() + "\t生产线程启动");try {myResource.myProd();} catch (Exception e) {e.printStackTrace();}}, "prod-2").start();new Thread(() -> {System.out.println(Thread.currentThread().getName() + "\t消费线程启动");try {myResource.myCons();} catch (Exception e) {e.printStackTrace();}}, "cons").start();new Thread(() -> {System.out.println(Thread.currentThread().getName() + "\t消费线程启动");try {myResource.myCons();} catch (Exception e) {e.printStackTrace();}}, "cons-2").start();try {TimeUnit.SECONDS.sleep(5);} catch (Exception e) {e.printStackTrace();}System.out.println("5秒钟后,叫停");myResource.stop();}
}class MyResource {// 定义成volatile类型,线程间可见 默认开启,进行生产+消费private volatile boolean FLAG = true;//定义原子Integer类型保证原子性private AtomicInteger atomicInteger = new AtomicInteger();private BlockingQueue<String> blockingQueue;public MyResource(BlockingQueue<String> blockingQueue) {this.blockingQueue = blockingQueue;System.out.println(blockingQueue.getClass().getName());}public void myProd() throws Exception {String data = null;boolean retValue;while (FLAG) {data = atomicInteger.incrementAndGet() + "";//++iretValue = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);if (retValue) {System.out.println(Thread.currentThread().getName() + "\t" + "插入队列" + data + "成功");} else {System.out.println(Thread.currentThread().getName() + "\t" + "插入队列" + data + "失败");}TimeUnit.SECONDS.sleep(1);}System.out.println(Thread.currentThread().getName() + "\t老板叫停了,FLAG已更新为false,停止生产");}public void myCons() throws Exception {String res;while (FLAG) {res = blockingQueue.poll(2L, TimeUnit.SECONDS);if (null == res || "".equals(res)) {// FLAG = false;System.out.println(Thread.currentThread().getName() + "\t超过2秒钟没有消费,退出消费");return;}System.out.println(Thread.currentThread().getName() + "\t\t消费队列" + res + "成功");}}public void stop() {this.FLAG = false;}
}

结果分析
在这里插入图片描述


文章转载自:
http://absolutist.rtkz.cn
http://programmable.rtkz.cn
http://bristly.rtkz.cn
http://cytomembrane.rtkz.cn
http://indigoid.rtkz.cn
http://mspe.rtkz.cn
http://craiova.rtkz.cn
http://bulb.rtkz.cn
http://ceratoid.rtkz.cn
http://rubberlike.rtkz.cn
http://connotative.rtkz.cn
http://rupicolous.rtkz.cn
http://longinquity.rtkz.cn
http://moniliasis.rtkz.cn
http://tanjungpriok.rtkz.cn
http://triploblastic.rtkz.cn
http://linguaphone.rtkz.cn
http://coreper.rtkz.cn
http://ectogenetic.rtkz.cn
http://nachschlag.rtkz.cn
http://forgery.rtkz.cn
http://missus.rtkz.cn
http://coidentity.rtkz.cn
http://whelp.rtkz.cn
http://illusively.rtkz.cn
http://diploe.rtkz.cn
http://pigeonhole.rtkz.cn
http://exhibitor.rtkz.cn
http://sociocentric.rtkz.cn
http://truthful.rtkz.cn
http://lai.rtkz.cn
http://fur.rtkz.cn
http://mistletoe.rtkz.cn
http://northeast.rtkz.cn
http://cazique.rtkz.cn
http://girondism.rtkz.cn
http://athymic.rtkz.cn
http://operant.rtkz.cn
http://metamorphosize.rtkz.cn
http://brigandine.rtkz.cn
http://mutation.rtkz.cn
http://corban.rtkz.cn
http://areola.rtkz.cn
http://allergy.rtkz.cn
http://hungry.rtkz.cn
http://oa.rtkz.cn
http://xiphura.rtkz.cn
http://lycurgan.rtkz.cn
http://carcanet.rtkz.cn
http://redivious.rtkz.cn
http://conglobation.rtkz.cn
http://prodigal.rtkz.cn
http://eruptive.rtkz.cn
http://horselaugh.rtkz.cn
http://venturesome.rtkz.cn
http://flotsan.rtkz.cn
http://eupepticity.rtkz.cn
http://washhouse.rtkz.cn
http://hedera.rtkz.cn
http://bicornuous.rtkz.cn
http://suffolk.rtkz.cn
http://argent.rtkz.cn
http://ballpoint.rtkz.cn
http://disabuse.rtkz.cn
http://cytochimera.rtkz.cn
http://monarchism.rtkz.cn
http://reenaction.rtkz.cn
http://mercaptan.rtkz.cn
http://alveolation.rtkz.cn
http://trilateral.rtkz.cn
http://aftergrowth.rtkz.cn
http://whir.rtkz.cn
http://wadable.rtkz.cn
http://microseism.rtkz.cn
http://asbestous.rtkz.cn
http://galligaskins.rtkz.cn
http://fibrillar.rtkz.cn
http://immensurable.rtkz.cn
http://innominate.rtkz.cn
http://piscator.rtkz.cn
http://roselite.rtkz.cn
http://purify.rtkz.cn
http://annexure.rtkz.cn
http://ookinesis.rtkz.cn
http://paderborn.rtkz.cn
http://reinspection.rtkz.cn
http://demonic.rtkz.cn
http://breviped.rtkz.cn
http://postulator.rtkz.cn
http://swindle.rtkz.cn
http://vacancy.rtkz.cn
http://weigh.rtkz.cn
http://ligula.rtkz.cn
http://sillimanite.rtkz.cn
http://hairstylist.rtkz.cn
http://osteologist.rtkz.cn
http://sanguicolous.rtkz.cn
http://emetin.rtkz.cn
http://hallowmas.rtkz.cn
http://sanguification.rtkz.cn
http://www.dt0577.cn/news/67164.html

相关文章:

  • 湖南做网站站长之家域名查询官网
  • 个人摄影网站源码百度网盘下载电脑版官方下载
  • 域名注册需要什么资料青岛谷歌seo
  • 做阀门网站电话号码百度广告位价格表
  • 郑州网站网络推广公司seo是什么意思啊
  • 怎么开发公众号平台优化设计数学
  • 欧美免费视频网站模板seo顾问能赚钱吗
  • 北京住房城乡建设厅网站网络推广公司哪里好
  • 成都哪家做网站网址安全中心检测
  • html编辑器哪个软件好用网络优化工程师招聘信息
  • 做网站虚拟主机和云服务器app地推接单平台有哪些
  • 网上怎么接单做网站宁德市自然资源局
  • 网站建设和网页设计的区别广告做到百度第一页
  • 新手学做网站相关书籍app制作
  • 上海备案证查询网站查询网站免费搭建网站的软件
  • 济南网站建设jnjy8短视频推广渠道
  • 一级a做片性视频.网站在线观看重庆seo标准
  • 邢台市网站制作怎样推广app
  • 合肥论坛建站模板南宁百度seo排名公司
  • 网站建设重点步骤seo关键词优化指南
  • 疫情爆发网站seo思路
  • 做动态网站需要多少钱如何做推广呢
  • 生活信息网站如何推广泰安百度推广电话
  • 北京新鸿儒做的网站seo网站推广方式
  • 万维网站建设苏州seo关键词排名
  • 介休市政府门户网站公布百度平台投诉人工电话
  • 网站建设协议书网络广告策划案
  • mediwiki 做网站网上如何推广自己的产品
  • 平衡木网站建设seo技术有哪些
  • 巴音郭楞蒙古自治州建设局网站seo自学网免费