CAS

Java并发多线程

我只是一个虾纸丫 提交于 2020-11-05 14:22:55
1.为什么要使用线程池 避免频繁地创建和销毁线程,达到线程对象的重用。另外,使用线程池还可以根据项目灵活地控制并发的数目。 2.java中如何获取到线程dump文件 死循环、死锁、阻塞、页面打开慢等问题,打线程dump是最好的解决问题的途径。所谓线程dump也就是线程堆栈,获取到线程堆栈有两步: 1)获取到线程的pid,可以通过使用jps命令,在Linux环境下还可以使用ps -ef | grep java 2)打印线程堆栈,可以通过使用jstack pid命令,在Linux环境下还可以使用kill -3 pid 另外提一点,Thread类提供了一个getStackTrace()方法也可以用于获取线程堆栈。这是一个实例方法,因此此方法是和具体线程实例绑定的,每次获取获取到的是具体某个线程当前运行的堆栈。 3.怎么检测一个线程是否持有对象监视器 我也是在网上看到一道多线程面试题才知道有方法可以判断某个线程是否持有对象监视器:Thread类提供了一个holdsLock(Object obj)方法,当且仅当对象obj的监视器被某条线程持有的时候才会返回true,注意这是一个static方法,这意味着"某条线程"指的是当前线程。 4.synchronized和ReentrantLock的区别 synchronized是和if、else、for、while一样的关键字

记一次订单号重复的事故,快看看你的 uuid 在并发下还正确吗?

与世无争的帅哥 提交于 2020-11-04 06:06:46
作者:funnyZpC cnblogs.com/funnyzpc/p/13541713.html 去年年底的时候,我们线上出了一次事故,这个事故的表象是这样的: 系统出现了两个一模一样的订单号,订单的内容却不是不一样的,而且系统在按照 订单号查询的时候一直抛错,也没法正常回调,而且事情发生的不止一次,所以 这次系统升级一定要解决掉。 经手的同事之前也改过几次,不过效果始终不好:总会出现订单号重复的问题, 所以趁着这次问题我好好的理了一下我同事写的代码。 这里简要展示下当时的代码: /** * OD单号生成 * 订单号生成规则:OD + yyMMddHHmmssSSS + 5位数(商户ID3位+随机数2位) 22位 */ public static String getYYMMDDHHNumber (String merchId) { StringBuffer orderNo = new StringBuffer( new SimpleDateFormat( "yyMMddHHmmssSSS" ).format( new Date())); if (StringUtils.isNotBlank(merchId)){ if (merchId.length()> 3 ){ orderNo.append(merchId.substring( 0 , 3 )); } else {

Java并发编程的艺术[1]

冷暖自知 提交于 2020-11-02 08:19:10
昨天阅读翻译了CompletableFuture的源码,目前百度,有道,基本是翻译效果一般,Google翻译比较准确,源码有很多注释,写个小测试类将其去掉,另外获得了《Java并发编程的艺术》PDF版,因为需要测试demo,就要转word,又找了个小测试类转成word,效果不错。参考《Java并发编程的艺术》 1.上下文切换 个人理解:CPU需要暂停当前任务,执行另一个任务,另一个任务完成后再执行当前任务,我们知道 时钟中断导致cpu切换进程 原文: CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。 2.多线程一定快吗? 书中demo public class Question1 { private static final long count = 10000L; public static void main(String[] args) throws InterruptedException { concurrency(); serial(); new CompletableFuture<>(); } private static void concurrency() throws

goroutine间的同步&协作

假如想象 提交于 2020-11-01 19:04:39
Go语言中的同步工具 基础概念 竞态条件(race condition) 一份数据被多个线程共享,可能会产生争用和冲突的情况。这种情况被称为竞态条件,竞态条件会破坏共享数据的一致性,影响一些线程中代码和流程的正确执行。 同步 同步可以解决竞态问题。它本质上是在控制多个线程对共享资源的访问。这种控制主要包含两点: 避免多个线程在同一时刻操作同一个数据块。 协调多个线程,以避免它们在同一时刻执行同一个代码块。 在同步控制下,多个并发运行的线程对这个共享资源的访问是完全串行的。对这个共享资源进行操作的代码片段可以视为一个临界区。 互斥量sync.Mutex 一个互斥锁可以被用来保护一个临界区或者一组相关临界区。它可以保证,在同一时刻只有一个 goroutine 处于该临界区之内。 每当有 goroutine 想进入临界区时,都需要先加锁,每个 goroutine 离开临界区时,都要及时解锁。 Mutex的使用 var mutex sync.Mutex func updatePublicResource() { mutex.Lock() doUpdate() mutex.Unlock() } 使用互斥锁的注意事项: 不要重复锁定互斥锁。 不要忘记解锁互斥锁,推荐使用defer。 不要对尚未锁定或者已解锁的互斥锁解锁。 不要在多个函数之间直接传递互斥锁。(即,不要复制锁)

面试官问我:创建线程有几种方式?我笑了

≡放荡痞女 提交于 2020-10-31 03:33:51
前言 多线程在面试中基本上已经是必问项了,面试官通常会从简单的问题开始发问,然后再一步一步的挖掘你的知识面。 比如,从线程是什么开始,线程和进程的区别,创建线程有几种方式,线程有几种状态,等等。 接下来自然就会引出线程池,Lock,Synchronized,JUC的各种并发包。然后就会引出 AQS、CAS、JMM、JVM等偏底层原理,一环扣一环。 这一节我们不聊其他的,只说创建线程有几种方式。 是不是感觉非常简单,不就是那个啥啥那几种么。 其实不然,只有我们给面试官解释清楚了,并加上我们自己的理解,才能在面试中加分。 正文 一般来说我们比较常用的有以下四种方式,下面先介绍它们的使用方法。然后,再说面试中怎样回答面试官的问题比较合适。 1、继承 Thread 类 通过继承 Thread 类,并重写它的 run 方法,我们就可以创建一个线程。 首先定义一个类来继承 Thread 类,重写 run 方法。 然后创建这个子类对象,并调用 start 方法启动线程。 2、实现 Runnable 接口 通过实现 Runnable ,并实现 run 方法,也可以创建一个线程。 首先定义一个类实现 Runnable 接口,并实现 run 方法。 然后创建 Runnable 实现类对象,并把它作为 target 传入 Thread 的构造函数中 最后调用 start 方法启动线程。 3、实现

还在用BlockingQueue?读这篇文章,了解下Disruptor吧

喜欢而已 提交于 2020-10-30 16:02:29
1.何为队列 听到队列相信大家对其并不陌生,在我们现实生活中队列随处可见,去超市结账,你会看见大家都会一排排的站得好好的,等待结账,为什么要站得一排排的,你想象一下大家都没有素质,一窝蜂的上去结账,不仅让这个超市崩溃,还会容易造成各种踩踏事件,当然这些事其实在我们现实中也是会经常发生。 当然在计算机世界中,队列是属于一种数据结构,队列采用的FIFO(first in firstout),新元素(等待进入队列的元素)总是被插入到尾部,而读取的时候总是从头部开始读取。在计算中队列一般用来做排队(如线程池的等待排队,锁的等待排队),用来做解耦(生产者消费者模式),异步等等。 2.jdk中的队列 在jdk中的队列都实现了java.util.Queue接口,在队列中又分为两类,一类是线程不安全的,ArrayDeque,LinkedList等等,还有一类都在java.util.concurrent包下属于线程安全,而在我们真实的环境中,我们的机器都是属于多线程,当多线程对同一个队列进行排队操作的时候,如果使用线程不安全会出现,覆盖数据,数据丢失等无法预测的事情,所以我们这个时候只能选择线程安全的队列。在jdk中提供的线程安全的队列下面简单列举部分队列: 队列名字 是否加锁 数据结构 关键技术点 是否有锁 是否有界 ArrayBlockingQueue 是 数组array

kuangbin数论专题记录

倾然丶 夕夏残阳落幕 提交于 2020-10-30 04:40:36
A: 每个学生所得的bamboo的score的值必须大于或等于他的幸运数字, bamboo的score值就是其长度x的欧拉函数值(即小于x且与x互质的数的个数) 每单位长度花费1Xukha,求买这些bamboo的最小花费。 此题关键:素数(x)的欧拉函数值(x-1)是满足条件(大于等于幸运数字)且花费最小的,相同欧拉函数值合数数值(花费)一定更大,所以只要筛出【1,1e6】的素数即可。 B: 二分图匹配 C: 给你面积为a的地毯并告诉你地毯的最小边长b,求出有多少种不同的地毯。 用到算术基本定理(唯一分解定理) 用第一条计算出a所有正因子的个数,除以2即得a正因子的对数,然后暴力枚举筛掉(1,b)以内的正因子对数 D: r(n)=n的全体正因数之和 给你一个n(n<=1e12),求出(1,n)内所有正因数和为偶数的数的个数 由公式可以推知,若要r(n)为奇数, 则每一个质因子的括号都要为奇数,除了2是偶数以外,其他素数都是奇数 于是抛开质因子2不谈,n都要包含其他的质因子的偶数个 即n是一个完全平方数,或者是完全平方数的两倍,于是用n-sqrt(n)-sqrt(n/2)即得到答案 E: 求n^k的前三位和后三位。 后三位很好求,用n^k(mod 1000)即可,避免溢出要用快速幂取模1000 前三位 假设n^k=10^a=10^(x+y),x是a的整数部分,y是小数部分

这 21 个刁钻的 HashMap 面试题,我把阿里面试官吊打了!

戏子无情 提交于 2020-10-28 21:00:58
程序员的成长之路 互联网/程序员/技术/资料共享 关注 阅读本文大概需要 8 分钟。 来自: cnblogs.com/Young111/p/11519952.html?utm_source=gold_browser_extension 1:HashMap 的数据结构? A:哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点。当链表长度超过 8 时,链表转换为红黑树。 transient Node < K , V >\ [\] table ; 2:HashMap 的工作原理? HashMap 底层是 hash 数组和单向链表实现,数组中的每个元素都是链表,由 Node 内部类(实现 Map.Entry接口)实现,HashMap 通过 put & get 方法存储和获取。 存储对象时,将 K/V 键值传给 put() 方法: ①、调用 hash(K) 方法计算 K 的 hash 值,然后结合数组长度,计算得数组下标; ②、调整数组大小(当容器中的元素个数大于 capacity * loadfactor 时,容器会进行扩容resize 为 2n); ③、i.如果 K 的 hash 值在 HashMap 中不存在,则执行插入,若存在,则发生碰撞; ii.如果 K 的 hash 值在 HashMap 中存在,且它们两者 equals 返回 true,则更新键值对; iii. 如果

Kafka消费者的使用和原理

↘锁芯ラ 提交于 2020-10-28 15:07:16
继上周的《Kafka生产者的使用和原理》,这周我们学习下消费者,仍然还是先从一个消费者的Hello World学起: public class Consumer { public static void main(String[] args) { // 1. 配置参数 Properties properties = new Properties(); properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); properties.put("bootstrap.servers", "localhost:9092"); properties.put("group.id", "group.demo"); // 2. 根据参数创建KafkaConsumer实例(消费者) KafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties); // 3. 订阅主题 consumer

高并发学习笔记

▼魔方 西西 提交于 2020-10-28 11:44:58
并发 概念 高并发 并发: 多个线程操作相同的资源,保证线程安全,合理使用资源 高并发: 服务能同时处理很多请求,提高程序性能 java 内存模型 Thread Stack 存储基本 变量:比如 int , long 等,或者对象句柄 或者方法 本地变量存在 栈上即 Thread Stack , 对象存在 堆上即Heap 一个本地变量也可能指向一个 对象引用。即引用存储在栈上, 对象是 存在堆上, 一个对象的方法和本地变量是存储在 Thread stack 上的,就算该对象存在 Heap堆上, 一个对象的成员变量 可能会随着这个对象存在 堆上,不管这个成员变量是 原始类型还是引用类型, 静态成员变量,跟随类的定义一起存在堆上, 堆上对象可以被持有该对象引用的线程访问, 一个线程可以访问一个对象,也可以访问该对象的成员变量 如果两个线程 持有 同一个对象的引用,或者调用了同一个对象的方法,线程都会持有对象的成员变量, 但是这两个线程都拥有这个对象的成员变量的 私有拷贝(所以并发时候就容易造成数据不一致) CPU与 Java Memory Model 内存模型 CPU Registers 即 CPU 寄存器 Main Memory 即 主存 同步八种操作 同步规则 总结 并发测试工具 postman , Apache Bench https://www.cnblogs.com