当前位置: 首页 > 编程笔记 >

Java并发编程之闭锁与栅栏的实现

呼延子安
2023-03-14
本文向大家介绍Java并发编程之闭锁与栅栏的实现,包括了Java并发编程之闭锁与栅栏的实现的使用技巧和注意事项,需要的朋友参考一下

一、前言

闭锁与栅栏是在多线程编程中的概念,因为在多线程中,我们不能控制线程的执行状态,所以给线程加锁,让其按照我们的想法有秩序的执行。

闭锁

CountDownLatch,实例化时需要传入一个int类型的数字(count),意为等待count个线程完成之后才能执行下一步动作。

如今天要做的事情是吃晚饭,再去散步。假设11个人相约晚饭后一起去散步,我们得等11个人全都吃完晚饭了才能出发去散步。简而言之就是做了才到达某一种状态。

栅栏

CyclicBarrier,实例化时需要传入一个int类型的数字(parties),意为等待parties个线程都准备就绪后才能执行自己的任务。

如今天要做的事情是吃晚饭,8个人约好一起去某餐厅吃饭,得等到人齐了才能去吃饭。简而言之就是到达某种状态后一起做。

二、实例

闭锁 CountDownLatch

package com.test;
 
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
 
public class Test {
 public static void main(String[] args) {
 CountDownLatch latch = new CountDownLatch(3);
 
        // 模拟三个任务
 List<String> jobs = new ArrayList<String>();
 jobs.add("first");
 jobs.add("second");
 jobs.add("third");
    
        // 循环执行任务
 for (String job : jobs) {
  new Thread(new Runnable() {
 
  @Override
  public void run() {
   System.out.println(Thread.currentThread().getName() + " : 进入run方法");
   latch.countDown();
   System.out.println(Thread.currentThread().getName() + " : 执行" + job);
  }
  }).start();
 }
 
 try {
  latch.await();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 // 任务都执行完后才执行
 System.out.println("回到main线程");
 }
 
}

执行结果:

Thread-1 : 进入run方法

Thread-2 : 进入run方法

Thread-2 : 执行third

Thread-0 : 进入run方法

Thread-1 : 执行second

Thread-0 : 执行first

回到main线程

通过执行结果可看出,当所有线程都执行完后才能回到主线程继续执行后面的输出。

栅栏 CyclicBarrier

package com.test;
 
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
 
public class Test {
 public static void main(String[] args) {
 CyclicBarrier barrier = new CyclicBarrier(3);
 // 模拟创建三个任务
 List<String> jobs = new ArrayList<String>();
 jobs.add("first");
 jobs.add("second");
 jobs.add("third");
 //循环执行任务
 for (String job : jobs) {
  new Thread(new Runnable() {
 
  @Override
  public void run() {
   System.out.println(Thread.currentThread().getName() + " : 进入run方法");
   try {
   // 等待
   barrier.await();
   } catch (InterruptedException | BrokenBarrierException e) {
   e.printStackTrace();
   }
   System.out.println(Thread.currentThread().getName() + " : 执行" + job);
  }
  }).start();
 }
 } 
}

执行结果:

Thread-1 : 进入run方法

Thread-2 : 进入run方法

Thread-0 : 进入run方法

Thread-0 : 执行first

Thread-1 : 执行second

Thread-2 : 执行third

通过执行结果可看出,当所有线程都执行都进入到run方法后,才能继续执行自己内部的方法。

到此这篇关于Java并发编程之闭锁与栅栏的实现的文章就介绍到这了,更多相关Java 闭锁与栅栏内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!

 类似资料:
  • 本文向大家介绍Java并发编程之ReentrantLock可重入锁的实例代码,包括了Java并发编程之ReentrantLock可重入锁的实例代码的使用技巧和注意事项,需要的朋友参考一下 目录 1.ReentrantLock可重入锁概述2.可重入3.可打断4.锁超时5.公平锁6.条件变量 Condition 1.ReentrantLock可重入锁概述 相对于 synchronized 它具备如下特

  • 本文向大家介绍Java并发问题之乐观锁与悲观锁,包括了Java并发问题之乐观锁与悲观锁的使用技巧和注意事项,需要的朋友参考一下 首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再

  • 问题内容: 我正在阅读《 实践Java并发 》一书。在第15章中,他们讨论了非阻塞算法和 比较交换 (CAS)方法。 据记载,CAS的性能比锁定方法好得多。 我想问一下已经使用这两个概念的人,并想听听您何时更喜欢这些概念中的哪一个? 真的那么快吗? 对我来说,锁的用法更加清晰,易于理解,甚至维护起来也更好 (如果我错了,请纠正我) 。我们是否应该真正专注于创建与CAS相关的并发代码,而不是锁定,以

  • 本文向大家介绍java并发编程之cas详解,包括了java并发编程之cas详解的使用技巧和注意事项,需要的朋友参考一下 CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术。简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替换当前变量的值。这听起来可能有一点复杂但是实际上你理解之后发现很简单,接下来,让

  • 本文向大家介绍Java并发编程如何降低锁粒度并实现性能优化,包括了Java并发编程如何降低锁粒度并实现性能优化的使用技巧和注意事项,需要的朋友参考一下 在高负载多线程应用中性能是非常重要的。为了达到更好的性能,开发者必须意识到并发的重要性。当我们需要使用并发时, 常常有一个资源必须被两个或多个线程共享。 在这种情况下,就存在一个竞争条件,也就是其中一个线程可以得到锁(锁与特定资源绑定),其他想要得

  • 背景 在并发编程方面,JDK提供了Future, 但是使用起来不是很方便,guava提供了ListenableFuture以简化并发的编写. ListenableFuture继承自Future. 接口 interface ListenableFuture<V> extends Future<V> void addListener(Runnable listener, Executor exe