技术标签: java
Unsafe提供了非常底层的,操作内存,线程的方法.Unsafe对象不能直接调用,只能通过反射获得.
import lombok.Data;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class TestUnsafe {
public static void main(String[] args) throws Exception {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe)theUnsafe.get(null);
System.out.println(unsafe);
// 1. 获取域的偏移地址
long idOffset = unsafe.objectFieldOffset(Student.class.getDeclaredField("id"));
long nameOffset = unsafe.objectFieldOffset(Student.class.getDeclaredField("name"));
Student student = new Student();
System.out.println(student);
// 2. 执行cas操作
unsafe.compareAndSwapInt(student,idOffset,0,1);
unsafe.compareAndSwapObject(student,nameOffset,null,"小明");
// 3. 验证
System.out.println(student);
}
}
@Data
class Student{
volatile int id;
volatile String name;
}
import sun.misc.Unsafe;
import java.util.ArrayList;
import java.util.List;
public class TestMyAtomicInteger {
public static void main(String[] args) {
Account.demo(new MyAtomicInteger(10000));
}
}
class MyAtomicInteger implements Account{
private volatile int value; // 使用cas,必须是volatile
private static final long valueOffset; // 获取域的偏移量
private static final Unsafe UNSAFE;
static{
UNSAFE = UnsafeAccessor.getUnsafe();
try {
valueOffset = UNSAFE.objectFieldOffset(MyAtomicInteger.class.getDeclaredField("value"));
} catch (NoSuchFieldException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public int getValue(){
return value;
}
public void decrement(int amount){
while(true){
int prev = this.value;
int next = prev - amount;
if(UNSAFE.compareAndSwapInt(this,valueOffset,prev,next)){
break;
}
}
}
public MyAtomicInteger(int value){
this.value = value;
}
@Override
public int getBalance() {
return value;
}
@Override
public void withdraw(int amount) {
decrement(amount);
}
}
interface Account{
// 设置余额
int getBalance();
void withdraw(int amount);
static void demo(Account account){
List<Thread> ts = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
// 创建1000个线程,每个线程减去10
ts.add(new Thread(()->{
account.withdraw(10);
}));
}
ts.forEach(Thread::start);
ts.forEach(t->{
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(account.getBalance());
}
}
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class UnsafeAccessor {
private static final Unsafe unsafe;
static{
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = (Unsafe)theUnsafe.get(null);
} catch (Exception e) {
throw new Error(e);
}
}
public static Unsafe getUnsafe(){
return unsafe;
}
}
文章浏览阅读7.3k次。yum服务器lvm扩容,data目录是yum存放rpm包的目录,只有20G,需要添加磁盘扩容到80G# df -lhFilesystem Size Used Avail Use% Mounted on/dev/mapper/vg_node5-root 20G 479M 18G 3% /tmpfs ..._虚拟机中将分区转化为物理卷时,提示can't open怎么解决
文章浏览阅读1.7k次。python_opencv使用鼠标获取图片的某一点坐标@[TOC]https://blog.csdn.net/jiangkui007/article/details/82866755_opencv返回图片坐标
文章浏览阅读67次。翻译:j_hao104原文:Introduction to MongoDB and Python 在这篇文章中,将向您展示如何使用Python链接目前主流的MongoDB(V3.4.0)数据库,主要使用PyMongo(v3.4.0)和MongoEngine(V0.10.7)。同时比..._python3.10支持mongo3.4吗
文章浏览阅读2k次。约束的优先级AutoLayout添加的约束中也有优先级(Priority),优先级的数值1~1000,分为两种情况:一种情况是我们经常添加的各种约束,默认值1000(最大值)优先执行,条件允许的话系统会自动满足我们的约束需求。第二种就是固有约束(intinsic content size)严格说这种更像UILabel和UIButton的一种属性,但是在Autolayout中需要满足属性取值..._ios auto layout priority
文章浏览阅读169次。游戏(Game)+金融(Finance)是GameFi最早时期在加密领域外的结合形式,当 GameFi 这个词来到加密领域,由于DEFI生态的成熟,它所指的已经不仅仅是Game+Finance,更是指“Game+DeFi”。而GameFi赛道也在2021年底迎来了爆发,随着元宇宙与NFT概念的爆火,GameFi也一扫早期加密猫“粗制滥造”固有印象的阴霾,从体验感以及即玩即赚等方向,都给予了玩家不一样的体验,例如最近大火的项目GMT,通过购买官方的跑步鞋NFT,然后参与到游戏中来,GMT市值也一度大._aquanee链游怎么玩
文章浏览阅读1.9k次,点赞2次,收藏7次。参考文章:https://mp.weixin.qq.com/s/XM1AEBVleaOe9LNe4cDaxg论文:《Rethinking ImageNet Pre-training》总结:(1)当数据量较少时,建议使用预训练模型,这样可以快速收敛,而且可以得到较好的精度;(2)数据量足够的情况下,预训练模型相比随机初始化可以更快收敛,但不能带来精度的提高。..._vgg16top1 74% 如何训练的
文章浏览阅读181次。描述正则表达式是一种字符模式,用于在查找过程中匹配制定的字符。元字符通常在Linux中分为两类:Shell元字符,由Linux Shell进行解析;正则表达式元字符,由vi/grep/sed/awk等文本处理工具进行解析;正则表达式一般以文本行进行处理,在进行下面实例之前,先为grep命令设置--color参数:这样每次过滤出来的字符串都会带色彩了。在开始之前还需要做一件事情,就是创建一个测试用的..._linux vi正则
文章浏览阅读1.1w次,点赞2次,收藏9次。现在网络上,有非常多的JS在线编译器,非常好用,特备是在调试某些片段代码的时候,比在本地重新新建文件来的方便快捷~ 非常流行的比如 JS.do、 jsfiddle、JSRUN 等等。而对于Vue来说,在线编译器有时候会显得更加必要,因为初始化一个Vue项目还是需要花一点时间的~并且需要安卓很多的依赖,费时费力。现在也有很多JS在线编译器已经支持Vue代码了,另外..._在线vue编译
文章浏览阅读1.5w次,点赞17次,收藏40次。此文转载别人,希望自己能够做完这些题目!1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276,1322, 1414, 1456, 1458, 1609, 1644, 1664, 1690, 1699, 1740(博弈),1742,_poj 动态规划 题集
文章浏览阅读240次。第一:用scala写一个wordcount程序***package com.scala.wordcountobject wordcountApp {def main(args: Array[String]): Unit = {//造一个List,模拟读取文件val wordlist= List(&amp;amp;quot;hello scala&amp;amp;quot;,&amp;amp;quot;hello word&_scala编写wordcount程序
文章浏览阅读337次。<?xml version="1.0" encoding="UTF-8" standalone="no"?><templates><template autoinsert="true" context="delegatecomment_context" deleted="false" description="Comment for delegate methods" enabled="true" id="org.eclipse.jdt.ui.text.codetemplate_semyxml
文章浏览阅读1k次。1. SELECT 关键字用法:检索单个列:select 列名 from 表名;例:select ename from emp;检索多个列: select [列1,列2, ... ,列N] from 表名;例:select ename , sal from emp;检索所有列:select * from 表名;例:select * from emp;2. 通配符(A):* :代表0个或多个列_ :..._oracle中 select 字段加.的用法