countdownlatch

Curator分布式锁之生成流水号

陌路散爱 提交于 2019-11-29 05:37:04
在分布式系统中,为了保证数据的一致性,往往需要进行同步控制,比如减库存、唯一流水号生成等。Curator对Zookeeper进行了封装,实现了分布式锁的功能,提供了线程的同步控制。同时,Curator也提供了多种锁机制。下面对通过时间戳生成流水号的场景进行逐步分析。 普通示例 先看一个简单的程序: package com.secbro.learn.curator; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by zhuzs on 2017/5/4. */ public class CreateOrderNo { public static void main (String[] args) { for ( int i= 0 ; i< 10 ; i++){ SimpleDateFormat sdf = new SimpleDateFormat( "yyyyDDmm HH:mm:ss|SSS" ); String orderNo = sdf.format( new Date()); System.out.println(orderNo); } } } 以上代码通过一个循环连续打印出10个时间戳。这里没有使用多线程,但分析下面的打印结果就会发现,其实在同一时刻会生成多个相同的流水号

【RPC】一步一步实现基于netty+zookeeper的RPC框架(一)

試著忘記壹切 提交于 2019-11-29 05:00:51
随着分布式架构运用的越来越多,RPC框架成为了我们不得不掌握的知识,这里一步一步来手写一个简单的RPC框架,以博文作为记录及自我监督。 首先是技术选型,这边我选用的是当前比较流行的Netty+Zookeeper来实现,通过zookeeper的特性来实现服务注册与发现,通信则使用netty框架。 这里贴出github代码地址,想直接看代码的可以直接下载运行: https://github.com/whiteBX/wrpc 这里先来讲服务注册发现原理: 利用zookeeper的创建临时节点和watcher机制,可以做到在一个服务下注册多个服务器地址,并且在节点发生变动时通过watcher动态更新服务器列表,来达到在新增/修改/删除时自动注册发现/删除/更新服务器连接信息 .这里说一点,zookeeper的增删改操作会交由leader去处理,所以这里不用担心并发问题. zookeeper相关代码如下: public class ZKClient { /** * 获取zookeeper连接 * * @param connectString * @param sessionTimeout * @return */ public ZooKeeper newConnection ( String connectString , int sessionTimeout ) { ZooKeeper

并发编程 Promise, Future 和 Callback

≯℡__Kan透↙ 提交于 2019-11-29 00:28:19
在并发编程中,我们通常会用到一组非阻塞的模型:Promise,Future 和 Callback。其中的 Future 表示一个可能还没有实际完成的异步任务的结果,针对这个结果可以添加 Callback 以便在任务执行成功或失败后做出对应的操作,而 Promise 交由任务执行者,任务执行者通过 Promise 可以标记任务完成或者失败。 可以说这一套模型是很多异步非阻塞架构的基础。 这一套经典的模型在 Scala、C# 中得到了原生的支持,但 JDK 中暂时还只有无 Callback 的 Future 出现,当然也并非在 JAVA 界就没有发展了,比如 Guava 就提供了ListenableFuture 接口,而 Netty 4+ 更是提供了完整的 Promise、Future 和 Listener 机制,在 Netty 的官方文档 Using as a generic library 中也介绍了将 Netty 作为一个 lib 包依赖,并且使用 Listenable futures 的示例。在实际的项目使用中,发现 Netty 的 EventLoop 机制不一定适用其他场景,因此想去除对 EventLoop 的依赖,实现一个简化版本。 参考 Scala 和 Netty 的代码重新定义了接口和实现,先介绍下和 Netty 版本的区别: 去除了对 EventLoop 的依赖

JUC之CountDownLatch和CyclicBarrier的区别 (转)

╄→гoц情女王★ 提交于 2019-11-29 00:04:27
CountDownLatch和CyclicBarrier的功能看起来很相似,不易区分,有一种谜之的神秘。本文将通过通俗的例子并结合代码讲解两者的使用方法和区别。 CountDownLatch和CyclicBarrier都是java.util.concurrent包下面的多线程工具类。 从字面上理解,CountDown表示减法计数,Latch表示门闩的意思,计数为0的时候就可以打开门闩了。Cyclic Barrier表示循环的障碍物。两个类都含有这一个意思:对应的线程都完成工作之后再进行下一步动作,也就是大家都准备好之后再进行下一步。然而两者最大的区别是,进行下一步动作的动作实施者是不一样的。这里的“动作实施者”有两种,一种是主线程(即执行main函数),另一种是执行任务的其他线程,后面叫这种线程为“其他线程”,区分于主线程。对于CountDownLatch,当计数为0的时候,下一步的动作实施者是main函数;对于CyclicBarrier,下一步动作实施者是“其他线程”。 下面举例说明: 对于CountDownLatch,其他线程为游戏玩家,比如英雄联盟,主线程为控制游戏开始的线程。在所有的玩家都准备好之前,主线程是处于等待状态的,也就是游戏不能开始。当所有的玩家准备好之后,下一步的动作实施者为主线程,即开始游戏。 我们使用代码模拟这个过程,我们模拟了三个玩家

java高并发系列 - 第32天:高并发中计数器的实现方式有哪些?

拟墨画扇 提交于 2019-11-28 19:49:13
这是java高并发系列第32篇文章。 java环境:jdk1.8。 本文主要内容 4种方式实现计数器功能,对比其性能 介绍LongAdder 介绍LongAccumulator 需求:一个jvm中实现一个计数器功能,需保证多线程情况下数据正确性。 我们来模拟50个线程,每个线程对计数器递增100万次,最终结果应该是5000万。 我们使用4种方式实现,看一下其性能,然后引出为什么需要使用 LongAdder 、 LongAccumulator 。 方式一:synchronized方式实现 package com.itsoku.chat32; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.LongAccumulator; /** * 跟着阿里p7学并发,微信公众号:javacode2018 */ public class Demo1 { static int count = 0;

Flexible CountDownLatch?

你离开我真会死。 提交于 2019-11-28 17:54:37
I have encountered a problem twice now whereby a producer thread produces N work items, submits them to an ExecutorService and then needs to wait until all N items have been processed. Caveats N is not known in advance . If it were I would simply create a CountDownLatch and then have producer thread await() until all work was complete. Using a CompletionService is inappropriate because although my producer thread needs to block (i.e. by calling take() ) there's no way of signalling that all work is complete , to cause the producer thread to stop waiting. My current favoured solution is to use

分布式锁实现

廉价感情. 提交于 2019-11-28 15:03:18
在微服务开发中常用的分布式有redis,zookeeper实现,下面就基于这两种分布式锁实现做一个总结: 1,zookeeper的分布式锁实现 基于ZooKeeper分布式锁的流程 在zookeeper指定节点(locks)下创建临时顺序节点node_n 获取locks下所有子节点children 对子节点按节点自增序号从小到大排序 判断本节点是不是第一个子节点,若是,则获取锁;若不是,则监听比该节点小的那个节点的删除事件 若监听事件生效,则回到第二步重新进行判断,直到获取到锁 具体实现 下面就具体使用java和zookeeper实现分布式锁,操作zookeeper使用的是apache提供的zookeeper的包。 通过实现Watch接口,实现process(WatchedEvent event)方法来实施监控,使CountDownLatch来完成监控, 在等待锁的时候使用CountDownLatch来计数,等到后进行countDown,停止等待,继续运行。 以下整体流程基本与上述描述流程一致,只是在监听的时候使用的是CountDownLatch来监听前一个节点。 (1) pom.xml <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3

redis 面试题 基础知识篇

牧云@^-^@ 提交于 2019-11-28 07:46:11
1.常见数据类型、常见指令、内部数据结构以及用途? 数据类型 常见指令 内部数据结构 用途 String (字符串) set get incr decr del 通过int/sds()作为存储结构,int存放整形数据,sds存放字节、字符串、浮点型数据 常见的get/set操作,存短信验证码,常规计数,微博数,粉丝数 List (列表) lpush rpush lpop rpop lrange redis3.2前,List类型的value对象内部以linkedlist或者ziplist来实现, 当list的元素个数和单个元素的长度比较小 的时候,采用ziplist(压缩列表)来实现来减少内存占用。 redis3.2后,采用的一种叫quicklist的数据结构来存储list,列表的底层都由quicklist实现 排行榜,最热、活跃度最高的数据、简单的消息队列等功能 Hash (散列) hset heget hexist hdel hashtable、ziplist,数据量小的时候用ziplist,多了用hashtable 存储结构化的用户信息,商品信息之类的对象 Set (集合) sadd spop srem smembers sunion intset(只包含整数型用)、hashtable 实现如共同关注、共同粉丝、共同喜好 Sorted-Set (有序集合) zadd

java Fork/Join pool, ExecutorService and CountDownLatch

ぃ、小莉子 提交于 2019-11-28 07:06:41
We have three different multi threading techniques in java - Fork/Join pool, Executor Service & CountDownLatch Fork/Join pool ( http://www.javacodegeeks.com/2011/02/java-forkjoin-parallel-programming.html ) The Fork/Join framework is designed to make divide-and-conquer algorithms easy to parallelize. That type of algorithms is perfect for problems that can be divided into two or more sub-problems of the same type. They use recursion to break down the problem to simple tasks until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a

JUC

你。 提交于 2019-11-28 06:24:05
JUC 回顾 1 NIO主要内容:Buffer、Channel 2 非阻塞式网络编程 今天任务 1 volatile的使用 2 原子变量和CAS算法 3 Lock接口 4 并发集合 5 同步工具类 第一节 JUC 概述 在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类, 用于定义类似于线程的自定义子系统,包括线程池,异步IO和轻量级任务框架;还提供了用于多线程上下文中的 Collection实现等。 第二节 volatile volatile:易变的,不稳定的 在并发编程中的三个特性: (1)互斥性(原子性) (2)内存可见性 (3)指令重排序 int b=20; int a=10; int c=a+b; volatile 关键字: 当多个线程进行操作共享数据时,可以保证内存中的数据是可见的;相较于 synchronized 是一种较为轻量级的同步策略; volatile 不具备"互斥性"; volatile 不能保证变量的"原子性"; synchronized和volatile的区别: (1)synchronized可以实现互斥性和内存可见性,不能禁止指令重排序。 (2)volatile可以实现内存可见性,禁止指令重排序,不能保证原子性。 案例演示:内存可见性 public class