美文网首页
多线程并发同步业务场景与解决方案

多线程并发同步业务场景与解决方案

作者: vincky倩 | 来源:发表于2018-03-05 13:44 被阅读0次

1)semaphore 信号量 (控制并发数)

业务场景1:假如现在有10个人去同一家公司面试,但是只有3个面试官,那么同一时间只有2个人面试,当3个人中的任意一个面试结束之后,等待的7个人又会有一个人可以去面试。

需求分析:人数=线程数     面试官=资源       正在面试=线程正在执行

            面试结束=线程执行结束           等待面试人数=线程阻塞

解决方案:信号量 semaphore

代码Demo:

public class SemaphoreTest implements Runnable {

private int num;

private Semaphore semaphore;

public SemaphoreTest(int num,Semaphore semaphore){

            this.num=num;

            this.semaphore=semaphore;

}

public void run() {

 try {

    semaphore.acquire();//获取信号量许可,才能进入

    System.out.println("面试者"+num+"进入房间……");

    Thread.sleep((long)Math.random()*10000);

   System.out.println("面试者"+num+"交谈中……");

   Thread.sleep((long)Math.random()*10000);

  System.out.println("面试者"+num+"离开房间……");

      semaphore.release();//释放信号量许可

 } catch (InterruptedException e) {

      e.printStackTrace();

} }

public static void main(String[] args) {

     final Semaphore s=new Semaphore(3);//并发数为3

     ExecutorService threadPool=Executors.newCachedThreadPool();//线程池

    for(int i=0;i<10;i++){

          threadPool.execute(new SemaphoreTest((i+1),s));

}

    threadPool.shutdown();

} }

2)Cyclicbarrier  同步屏障(用于多线程计算数据,最后合并计算结果)

业务场景2:公司周末组织去聚餐、首先各自从家里出发到聚餐地点,当所有人全部到齐之后才开始吃饭,如果未到齐,到的人就只能等待在那里,直到所有人都到达之后,才可以一起做事。

案例代码:

public class CyclicbarrierDemo {

public static void main(String[] args) {

 final CyclicBarrier cb=new CyclicBarrier(3,new Runnable() {

 public void run() {

           System.out.println("吃饭前,一起做的事情"); } });

            ExecutorService threadPool=Executors.newCachedThreadPool();//线程池

          for(int i=0;i<3;i++){

            final int user=i+1;

                         Runnable r=new Runnable() {

                           public void run() {

                                try {

                                     Thread.sleep((long)Math.random()*10000);

                                       System.out.println(user+"到达聚餐地点,当前已有"+(cb.getNumberWaiting()+1)+"人到达");

                        cb.await();//等待,只有当线程都到达之后,才能往下走

                       if(user==1){ System.out.println("人员到齐"); }

                          Thread.sleep((long)Math.random()*10000);

                        System.out.println(user+"吃完饭,回家……");

 //dosometing

 } catch (Exception e) {

 e.printStackTrace(); } } };

 threadPool.execute(r);

 }

threadPool.shutdown();

 } }

3)Exchanger 线程之间交换数据

public class ExchangerDemo {

public static void main(String[] args) {

final Exchangerexchanger=new Exchanger();

 ExecutorService threadPool=Executors.newCachedThreadPool();//线程池

threadPool.execute(new Runnable() {

public void run() { String sc="a";

 try {

String js=exchanger.exchange(sc);//js=b

 } catch (InterruptedException e) { e.printStackTrace(); } } });

 threadPool.execute(new Runnable() {

 public void run() {

String sc="b";

try { String js=exchanger.exchange(sc);//js=a

 } catch (InterruptedException e) { e.printStackTrace(); } } }); } }

执行后,连个线程的数据进行了交换。

4)CountDownLatch 倒计时器

业务场景4:有一个任务a,他需要等待其他几个任务(BCD)都执行完毕之后才能来执行这个任务。

public static void main(String[] args) throws InterruptedException {

final CountDownLatch latch=new CountDownLatch(3);

 new Thread(){

public void run() {

 System.out.println("子任务B"+Thread.currentThread().getName()+"正在执行"); latch.countDown();//倒计时减一

}; }.start();

new Thread(){

 public void run() {

System.out.println("子任务C"+Thread.currentThread().getName()+"正在执行"); latch.countDown();//倒计时减一

 }; }.start();

new Thread(){

public void run() {

System.out.println("子任务D"+Thread.currentThread().getName()+"正在执行"); latch.countDown();//倒计时减一

 }; }.start();

System.out.println("等待3个任务执行完毕,"+Thread.currentThread().getName()+"组任务开始执行。");

latch.await();

System.out.println("继续执行主任务!");

}

CountDownLatch 与Cyclicbarrier 的区别:

1)共同点:都能够实现线程之间的等待。

2)不同点:

CountDownLatch :1)一般用于某个线程A等待其他若干线程执行完任务后,它才能执行。2)它是不能够重复用的。

Cyclicbarrier :1)一般用于一组线程互相等待,然后这一组线程同时执行。2)它可以重复使用。

相关文章

  • 多线程并发同步业务场景与解决方案

    1)semaphore 信号量 (控制并发数) 业务场景1:假如现在有10个人去同一家公司面试,但是只有3个面试官...

  • JAVA并发编程之多线程并发同步业务场景与解决方案

    Java并发编程是一个很热点的话题,无论在面试时候还是在高并发的场景中。都会涉及到Java的并发编程相关的知识。J...

  • iOS控制并发数

    并发是我们在多线程操作和资源限制时经常碰到的业务场景,解决方案也有很多,这里记录两种。1.使用NSOperatio...

  • 多线程

    GCD NSOperation NSThread 多线程与锁 一、GCD 同步、异步 和 串行、并发 dispat...

  • 理解java集合

    容器的同步控制与只读设置 一、同步控制:多线程并发访问集合的线程安全常用的容器ArrayList、HashSet、...

  • 第一章

    Java并发编程与高并发解决方案知识点:线程安全;线程封闭;线程调度;同步容器;并发容器;AQS;J.UC 高并发...

  • 多线程相关面试问题

    多线程:GCD、NSOperation、NSThread。 一、GCD 1、同步/异步 和 串行/并发(1)、同步...

  • 2021-03-01 深度剖析并发锁之AQS设计思想及原理

    深度剖析并发锁之AQS设计思想及原理 了解锁的场景和基本原理 多线程并发处理,没有同步导致结果异常本质上是由于++...

  • 分布式锁原理与实战

    在单体的应用开发场景中,涉及并发同步的时候,大家往往采用synchronized或者Lock的方式来解决多线程间的...

  • Java多线程并发之同步容器和并发容器-第一篇

    Java多线程并发之同步容器和并发容器-第一篇 概述 本文主要讲解在Java多线程并发开发中,集合中有哪些支持并发...

网友评论

      本文标题:多线程并发同步业务场景与解决方案

      本文链接:https://www.haomeiwen.com/subject/eufhfftx.html