使用CAS代替synchronized

在开发当中需要经常用到synchronized保证代码线程安全,在竞争条件下会阻塞等待资源,如果允许竞争不到资源返回失败,就可以使用cas减少阻塞时间。先来看一个cas的单例模式。

public class NonBlock {private static volatile NonBlock nonBlock;private static AtomicBoolean atomicBoolean = new AtomicBoolean(false);public static NonBlock getInstance() {if (nonBlock == null) {if (atomicBoolean.compareAndSet(false, true)) {nonBlock = new NonBlock();}}return nonBlock;}
}

在这个单例模式中,不同于synchronized的阻塞,多线程环境下,getInstance确保只会创建一个对象的情况下,可能返回的nonBlock是一个空对象。但,如果允许返回空对象的情况下,

	public class RedPacket {private long balance;private int num;public RedPacket(long balance, int num) {this.balance = balance;this.num = num;}public long get() {if (balance < 1 || num < 1) {return -1;}if (num == 1) {long result = balance;balance = 0;num--;return result;}long average = balance / num;long result = ThreadLocalRandom.current().nextLong(1, average * 2);balance -= result;num--;return result;}

我们还可以使用cas达到非阻塞的目的,这样能保证线程安全,出现竞争情况就提示抢失败,确点就是提示抢失败还可能余额大于0,先来不一定能抢到,后来人还能抢。

public class RedPacket {private long balance;private AtomicInteger num;public RedPacket(long balance, int num) {this.balance = balance;this.num = new AtomicInteger(num);}public long get() {int number = num.get();long balan = balance;if (balan < 1 || number < 1) {return -1;}if (num.compareAndSet(number, number - 1)) {if (number - 1 == 0) {balance = 0;return balan;}long average = balan / number;long result = ThreadLocalRandom.current().nextLong(1, average * 2);balance -= result;}return -1;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555630.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 获取图片的高度_uni-app获取元素高度等信息,并设置元素top信息

本文主要简介uni-app获取元素信息及设置信息等获取元素高度可查看官方文档mounted() {const query uni.createSelectorQuery().in(this);query.select(#editor).boundingClientRect(data > {console.log(data)}).exec();},这里的data用于获取这个元素大小及位置信息&#x…

关于java中线程yield()方法问题

关于java中线程yield()方法问题 问题一&#xff1a; 我知道yield是用来休眠当前线程&#xff0c;但我查看了资料&#xff0c;又说其不会释放锁&#xff0c;所以我就不解了&#xff0c;其明明会将cpu资源给其他线程&#xff0c;那它不释放锁&#xff0c;其他线程有怎么获取cpu资…

Lisp尺寸标注增加前后缀_求一CAD标注加前缀与后缀lisp

回答&#xff1a;1.计算所有线段总长度(加载后只需框选所有线段便可得出这些线段的总长度)(defun c:LL ()(setvar "cmdecho" 1)(setq en (ssget(list (0 . "spline,arc,line,ellipse,LWPOLYLINE"))))(setq i 0)(setq ll 0)(repeat (sslength en)(setq ss (…

beetl 页面标签_05.Beetl标签函数以及定界符、占位符介绍---《Beetl视频课程》

标签函数 layout所谓标签函数&#xff0c;即允许处理模板文件里的一块内容&#xff0c;功能等于同jsp tag。如Beetl内置的layout标签index.htmllayout("/inc/layout.html",{title:主题}){%>Hello,this is main partlayout.htmltitle is ${title}body content ${la…

hql实例 jpa_SpringBoot学习笔记九:Spring Data Jpa的使用

Spring Data Jpa 简介JPAJPA(Java Persistence API)意即Java持久化API&#xff0c;是Sun官方在JDK5.0后提出的Java持久化规范(JSR 338&#xff0c;这些接口所在包为javax.persistence&#xff0c;详细内容可参考https://github.com/javaee/jpa-spec)JPA的出现主要是为了简化持久…

Objects.requireNonNull 方法说明

在写代码的时候,Idea经常会提醒我们可以使用这个方法来进行参数非空检查, 这个方法的源码也非常简单, 如下所示: /*** Checks that the specified object reference is not {code null}. This* method is designed primarily for doing parameter validation in methods* and …

Java service层获取HttpServletRequest工具类的方法

大家都知道 能在Controller/action层获取HttpServletRequest &#xff0c;但是这里给大家备份的是从代码内部service层获取HttpServletRequest工具类。 具体如下&#xff1a; package com.base.common.sessionutils; import javax.servlet.http.HttpServletRequest; import j…

正则表达式发明者_浅谈正则表达式背后的基本原理

一、写在前面搞编程的都知道正则表达式是什么东西&#xff0c;这里就不多啰嗦了&#xff0c;需要强调的是&#xff0c;这篇文章并不是教你怎么去使用用正则表达式&#xff0c;正则表达式的语法并不是本文的重点&#xff0c;这篇文章的目的就是剥开正则表达式的语法糖&#xff0…

Java8 - 使用 Comparator.comparing 进行排序

使用外部比较器Comparator进行排序 当我们需要对集合的元素进行排序的时候&#xff0c;可以使用java.util.Comparator 创建一个比较器来进行排序。Comparator接口同样也是一个函数式接口&#xff0c;我们可以把使用lambda表达式。如下示例&#xff0c; package com.common;im…

cairo填充_Cairo 图形指南 (5) —— 形状与填充

这一部分&#xff0c;讲述一些基本的以及较为高级的形状绘制及其纯色 (solid color)、图案 (pattern) 与渐变 (gradient) 填充方法。基本形状Cairo 提供了几个用于绘制基本形状的函数。#include#include#includestatic gbooleanon_expose_event (GtkWidget * widget,GdkEventEx…

java集合进行排序的两种方式

java集合的工具类Collections中提供了两种排序的方法,分别是: Collections.sort(List list)Collections.sort(List list,Comparator c) 第一种称为自然排序,参与排序的对象需实现comparable接口,重写其compareTo()方法,方法体中实现对象的比较大小规则,示例如下: 实体类:(基本…

ubuntu编写python脚本_python在ubuntu中的几种方法(小结)

通过ubuntu官方的apt工具包安装通过PPA(Personal Package Archive) 的apt工具包安装通过编译python源代码安装通过ubuntu官方的apt工具包安装安装完成后&#xff0c; 可以用下面的命令进行确认从PPA(Personal Package Archives) 安装apt工具包类似使用apt工具包安装python的工…

Java中String类中compareTo( )方法

compareTo方法是比较简单的&#xff0c;我们可以直接看其源码: 源码如下&#xff1a; public int compareTo(String anotherString) {int len1 value.length;int len2 anotherString.value.length;int lim Math.min(len1, len2);char v1[] value;char v2[] anotherString…

python elif可以单独使用_Python的elif语句怎么用

else和elif语句也可以叫做子句&#xff0c;因为它们不能独立使用&#xff0c;两者都是出现在if、for、while语句内部的。else子句可以增加一种选择&#xff1b;而elif子句则是需要检查更多条件时会被使用&#xff0c;与if和else一同使用&#xff0c;elif是else if 的简写。if和…

SpringMVC接收哪些类型参数参数

支持的数据类型&#xff1a; 基本类型参数&#xff1a; 包括基本类型和 String 类型 POJO 类型参数&#xff1a; 包括实体类&#xff0c;以及关联的实体类 数组和集合类型参数&#xff1a; 包括 List 结构和 Map 结构的集合&#xff08;包括数组&#xff09; SpringMVC …

禁用当前的账户win7_系统小技巧:服务客人 开启Windows 10来宾账户

出于安全考虑&#xff0c;Windows 10默认以管理员账户登录&#xff0c;没有开启来宾账户。但对于那些只需在电脑上浏览网页或收看电子邮件的用户&#xff0c;给他们开启来宾账户非常必要。来宾权限或账户的开启&#xff0c;可以通过下面的两种方法。1. 通过系统设置 开启来宾权…

Java之接口的静态方法的定义和使用

格式如下&#xff1a;&#xff08;就是将abstract或者default换成ststic即可&#xff0c;带上方法体&#xff09; public static 返回值类型 方法名称&#xff08;参数列表&#xff09;{方法体----}代码如下&#xff1a; //定义一个接口 public interface MyInterfaceStatic …

三阶魔方还原步骤图_三阶魔方公式图解、教程

三阶魔方公式、魔方图解、魔方教程&#xff0c;从零基础到精通&#xff01;魔方还原法 Rubics Cube Solution ————先看理论“魔方的还原方法很多精彩内容&#xff0c;尽在百度攻略&#xff1a;https://gl.baidu.com在这里向大家介绍一种比较简单的魔方六面还原方法。这种方…

通俗易懂告诉你CPU/GPU是什么?

通俗易懂告诉你CPU/GPU是什么&#xff1f; CPU CPU( Central Processing Unit, 中央处理器)就是机器的“大脑”&#xff0c;也是布局谋略、发号施令、控制行动的“总司令官”。 CPU的结构主要包括运算器&#xff08;ALU, Arithmetic and Logic Unit&#xff09;、控制单元&a…

mysql正在加载_mysql 数据库基本操作

CREATE TABLE classes(id INT PRIMARY KEY AUTO_INCREMENT COMMENT班级表id,name VARCHAR(20) COMMENT班级名称);运行DESCRIBE classes;--------------------------------------------------------| Field | Type | Null | Key | Default | Extra |---------------------------…