Java详解多线程协作作业之信号同步

目录
  • 一、信号同步
  • 二、基于时间维度
    • 1、CountDownLatch
    • 2、CyclicBarrier
  • 三、基于信号维度

一、信号同步

多线程很多时候是协作作业。比如4个线程对电商数据分季度统计,统计完成之后,再汇总。如何知道4个线程都执行完成呢,我们可以使用JDK1.5给我们提供的辅助类CountDownLatch(

减少计数)、CyclicBarrier(循环栅栏)、Semaphore(信号灯)。

二、基于时间维度

1、CountDownLatch

多少个协作线程就初始化CountDownLatch的构造参数是多少。

 public static void main(String[] args) throws InterruptedException {
        final int NUM=6;
        //定义总数量;
        CountDownLatch countDownLatch=new CountDownLatch(NUM);
        for (int i = 0; i < NUM; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"线程,已执行!");
                //减少计数
                countDownLatch.countDown();
            },String.valueOf(i+1)).start();
        }
        //等待所有任务完成
        countDownLatch.await();
        System.out.println("所有线程任务已经执行完成!");
    }

2、CyclicBarrier

与减少计数类似

 public static void main(String[] args) {
        final int NUM = 6;
        //定义循环数量及循环完成后的任务(Runnable接口实现);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(NUM, () -> {
            System.out.println("所有线程任务已经执行完成!");
        });
        for (int i = 0; i < NUM; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"线程,已执行!");
                try {
                    //等待点或障碍点,等待所有任务完成,
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i+1)).start();
        }
    }

三、基于信号维度

Semaphore,线程与信号是m:n,其中m>=n。

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/*信号灯
* 6个线程,抢占三个信号
* */
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore=new Semaphore(3);
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                try {
                    //获取信号
                    semaphore.acquire();
                    System.out.println("线程:"+Thread.currentThread().getName()+"----获取信号");
                    int time = new Random().nextInt(5);
                    System.out.println(("线程:"+Thread.currentThread().getName()+"----休眠"+time+"s!"));
                    TimeUnit.SECONDS.sleep(time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                //    释放信号
                    System.out.println("线程:"+Thread.currentThread().getName()+"---释放信号");
                    semaphore.release();
                }
            },String.valueOf(i+1)).start();
        }
    }
}

首先线程4、1、3获取到信号,线程1释放信号后,线程2获得信号。线程2、3释放信号后,线程5、6获得信号。

到此这篇关于Java详解多线程协作作业之信号同步的文章就介绍到这了,更多相关Java信号同步内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 学习Java多线程之同步

    如果你的java基础较弱,或者不大了解java多线程请先看这篇文章<学习Java多线程之线程定义.状态和属性> 同步一直是java多线程的难点,在我们做android开发时也很少应用,但这并不是我们不熟悉同步的理由.希望这篇文章能使更多的人能够了解并且应用java的同步. 在多线程的应用中,两个或者两个以上的线程需要共享对同一个数据的存取.如果两个线程存取相同的对象,并且每一个线程都调用了修改该对象的方法,这种情况通常成为竞争条件. 竞争条件最容易理解的例子就是:比如火车卖票,火车票是一定的,

  • java多线程的同步方法实例代码

    java多线程的同步方法实例代码 先看一个段有关银行存钱的代码: class Bank { private int sum; public void add(int num){ sum = sum + num; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("total num is : " + sum); } } class Cu

  • Java多线程按指定顺序同步执行

    笔者今天看到一个有趣的面试题,如何让多个线程按照既定的顺序依次执行?比如每个线程输出一个整数, 那么期望就是这样的:0,1,2,3,4,5,6,7,8,9. 而不是0,2,4,1,3,5,8,7,9,6 乍一看,这不是反人性的考题吗?多线程本来就以乱序执行出名的.稍加思索,想到3种解决方案,分别用代码实现之. 方法1 使用newSingleThreadExecutor newSingleThreadExecutor返回仅仅包含一个线程的线程池,将多个任务交给此Executor时,这个线程池处理完

  • Java多线程之线程同步

    volatile 先看个例子 class Test { // 定义一个全局变量 private boolean isRun = true; // 从主线程调用发起 public void process() { test(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } stop(); } // 启动一个子线程循环读取isRun private void test() {

  • Java 多线程的同步代码块详解

    目录 synchronized 同步代码块 同步方法(this锁) 静态同步方法 死锁问题 lock 总结 火车站抢票问题 由于现实中买票也不会是零延迟的,为了真实性加入了延迟机制,也就是线程休眠语句 package test.MyThread.ticketDemo; public class RunnableThread implements Runnable{ private int ticket = 100; @Override public void run(){ while(true)

  • java 多线程的同步几种方法

    java 多线程的同步几种方法 一.引言 前几天面试,被大师虐残了,好多基础知识必须得重新拿起来啊.闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子,如果一个银行账户同时被两个线程操作,一个取100块,一个存钱100块.假设账户原本有0块,如果取钱线程和存钱线程同时发生,会出现什么结果呢?取钱不成功,账户余额是100.取钱成功了,账户余额是0.那到底是哪个

  • 五种Java多线程同步的方法

    为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举 个例子,如果一个银行账户同时被两个线程操作,一个取100块,一个存钱100块.假设账户原本有0块,如果取钱线程和存钱线程同时发生,会出现什么结果 呢?取钱不成功,账户余额是100.取钱成功了,账户余额是0.那到底是哪个呢?很难说清楚.因此多线程同步就是要解决这个问题. 一.不同步时的代码 Bank.java package threadTe

  • Java详解多线程协作作业之信号同步

    目录 一.信号同步 二.基于时间维度 1.CountDownLatch 2.CyclicBarrier 三.基于信号维度 一.信号同步 多线程很多时候是协作作业.比如4个线程对电商数据分季度统计,统计完成之后,再汇总.如何知道4个线程都执行完成呢,我们可以使用JDK1.5给我们提供的辅助类CountDownLatch( 减少计数).CyclicBarrier(循环栅栏).Semaphore(信号灯). 二.基于时间维度 1.CountDownLatch 多少个协作线程就初始化CountDownL

  • Java详解实现多线程的四种方式总结

    目录 前言 一.四种方式实现多线程 1.继承Thread类创建线程 2.实现Runnable接口创建线程 3.实现Callable接口 4.实现有返回结果的线程 二.多线程相关知识 1.Runnable 和 Callable 的区别 2.如何启动一个新线程.调用 start 和 run 方法的区别 3.线程相关的基本方法 4.wait()和 sleep()的区别 5.多线程原理 前言 Java多线程实现方式主要有四种: ① 继承Thread类.实现Runnable接口 ② 实现Callable接

  • Java 详解循环屏障CyclicBarrier如何实现多线程分段等待执行完成

    前言 工作中是否有这样的场景,多个线程任务,如果所有线程完成到某个阶段,你希望知道所有线程均完成该阶段.当然你使用线程计数可以实现,只是不够优雅. 所以我即:Java 多线程等待优雅的实现方式之Phaser同步屏障 之后再提供一个循环屏障,CyclicBarrier,更优雅的实现工具. Maven依赖 可以依赖,也可以不依赖,只是代码要稍微多一些,最好添加. <dependency> <groupId>org.projectlombok</groupId> <ar

  • Java 详解Collection集合之ArrayList和HashSet

    目录 Collection List ArrayList Set HashSet ArrayList和HashSet的区别 泛型 Collection Collection接口被List接口和Set接口继承 本章只介绍常用的集合 List ArrayList是List接口的实现类 ArrayList ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素. ArrayList 继承了 AbstractList ,并实现了 List 接口

  • Java 详解Collection集合之ArrayList和HashSet

    目录 Collection List ArrayList Set HashSet ArrayList和HashSet的区别 泛型 Collection Collection接口被List接口和Set接口继承 本章只介绍常用的集合 List ArrayList是List接口的实现类 ArrayList ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素. ArrayList 继承了 AbstractList ,并实现了 List 接口

  • Java详解使用线程池处理任务方法

    什么是线程池? 线程池就是一个可以复用线程的技术. 不使用线程池的问题: 如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能. 线程池常见面试题: 1.临时线程什么时候创建? 新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程. 2.什么时候会开始拒绝任务? 核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始任务拒绝. 1.线程池处理Runnable任务

  • java 详解类加载器的双亲委派及打破双亲委派

    java 详解类加载器的双亲委派及打破双亲委派 一般的场景中使用Java默认的类加载器即可,但有时为了达到某种目的又不得不实现自己的类加载器,例如为了达到类库的互相隔离,例如为了达到热部署重加载功能.这时就需要自己定义类加载器,每个类加载器加载各自的类库资源,以此达到资源隔离效果.在对资源的加载上可以沿用双亲委派机制,也可以打破双亲委派机制. 一.沿用双亲委派机制自定义类加载器很简单,只需继承ClassLoader类并重写findClass方法即可.如下例子: ①先定义一个待加载的类Test,它

  • Java 详解单向加密--MD5、SHA和HMAC及简单实现实例

    Java 详解单向加密--MD5.SHA和HMAC及简单实现实例 概要: MD5.SHA.HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法. MD5 MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致.MD5是输入不定长度信息,输出固定长度128-bits的算法. MD5算法具有以下特点: 1.压缩性:任意长度的数据,算出的MD5值长度都是固定的. 2.容易计算:从原数据计算出MD5值很容易. 3.抗修改性:对原数据进行任何

  • Java详解线上内存暴涨问题定位和解决方案

    前因: 因为REST规范,定义资源获取接口使用GET请求,参数拼接在url上. 如果按上述定义,当参数过长,超过tomcat默认配置 max-http-header-size :8kb 会报一下错误信息: Request header is too large 可以修改springboot配置,调整请求头大小 server: max-http-header-size: xxx 后果: 如果max-http-header-size设置过大,会导致接口吞吐下降,jvm oom,内存泄漏. 因为tom

  • Java 详解异常的处理机制

    目录 1.异常概述与异常体系结构 1.1异常概述 1.2运行时异常与编译时异常 1.3异常体系结构 2.常见异常 1. ArrayIndexOutOfBoundsException 2.NullPointerException 3.ArithmeticException 4.ClassCastException 3.异常处理机制 3.1异常的抛出与捕获 3.2异常处理机制:try-catch-finally 5.用户自定义异常类 6.异常处理5个关键字 1.异常概述与异常体系结构 1.1异常概述

随机推荐