自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(43)
  • 收藏
  • 关注

翻译 关于自定义资源共享方式

AQS支持两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。这样方便使用者实现不同类型的同步组件,独占式如ReentrantLock,共享式如Semaphore,CountDownLatch,组合式的如ReentrantReadWriteLock。总之,AQS为使用提供了底层支撑,如何组装实现,使用者可以自由发挥。

2024-08-29 11:45:17 10

原创 TreeSet对应的ConcurrentSkipListSet

理由很简单,因为addAll、removeAll、retainAll底层调用的还是contains、add、remove的方法,在批量操作时,只能保证每一次的contains、add、remove的操作是原子性的(即在进行contains、add、remove三个操作时,不会被其他线程打断),而不能保证每一次批量的操作都不会被其他线程打断。另外,ConcurrentSkipListSet类不允许使用 null 元素,因为无法可靠地将 null 参数及返回值与不存在的元素区分开来。和其他的Set集合一样,

2024-08-29 11:44:33 110

原创 HashSet对应的CopyOnWriteArraySet

CopyOnWriteArraySet是线程安全的,它底层的实现使用了CopyOnWriteArrayList,因此和CopyOnWriteArrayList概念是类似的。使用迭代器进行遍历的速度很快,并且不会与其他线程发生冲突。在构造迭代器时,迭代器依赖于不可变的数组快照,所以迭代器不支持可变的 remove 操作。

2024-08-29 11:44:14 109

翻译 ArrayList对应的CopyOnWriteArrayList

通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。而在CopyOnWriteArrayList写的过程是会加锁的,即调用add的时候,否则多线程写的时候会Copy出N个副本出来。

2024-08-27 11:05:46 18

原创 【无标题】

而且同步容器也并不是绝对线程安全的,在一些特殊情况下也会出现线程不安全的行为。那么有没有更好的方式代替同步容器呢?答案是有的,那就是并发容器,

2024-08-27 11:05:13 123

原创 实现线程封闭的方式

ThreadLocal 线程封闭:特别好的封闭方法,每个Thread线程内部都有个map,这个map是以线程本地对象作为key,以线程的变量副本作为value。所以对于不同的线程,每次获取副本值的时候,其他线程都不能获取当前线程的副本值,于是就形成了副本的隔离,多个线程互不干扰。堆栈封闭:局部变量,无并发问题。当多个线程访问同一个方法的时候,方法内的局部变量都会被拷贝一份副本到线程的栈中,所以局部变量是不会被多个线程所共享的,因此无并发问题。Ad-hoc 线程封闭:完全由程序控制实现,最糟糕的方式,忽略。

2024-08-27 11:03:18 174

原创 静态内部类来实现单例

这种方式更简单,既不需要判空也不需要加volatile关键字去防止指令重排序的问题。* 静态内部类创建单例对象,懒汉方式,需要的时候才进行加载。现单例模式的方式有很多种,除了以上所提到的,我们还可以使用。* @note : 静态内部类地方式来实现单例。* @author : l00379880 梁山广。* 静态工厂方法--获取实例。静态内部类来实现单例。

2024-08-25 23:45:00 278

原创 双重同步锁的懒汉式单例+volatile防止指令重排序

我们需要给instance对象增加一个volatile关键字进行修饰,这样就不会出现指令重排的情况了。如此在线程B看来,instance对象的引用要么指向null,要么指向一个初始化完毕的Instance,而不会出现某个中间态,保证了安全。经过volatile的修饰,当线程A执行instance = new Singleton的时候,JVM执行顺序是什么样?3.instance = memory // 设置instance指向刚分配的内存。2.ctorInstance() // 初始化对象。

2024-08-25 23:43:43 209

翻译 双重同步锁的懒汉式单例

众所周知,单例模式是最常用的设计模式了。Spring容器中所管理的类的实例默认也是单例的,虽然单例看似简单,但也是有不少需要注意的地方,特别是在多线程环境下。基础的单例模式实现方式就不赘述了,我们来看看为什么采用了双重同步锁的懒汉式单例还是线程不安全的。* @note : 双重同步锁懒汉式单例--线程不安全。* @author : l00379880 梁山广。

2024-08-25 23:43:01 15

翻译 安全发布对象的四种方法

在静态初始化函数中初始化一个对象的引用 将对象的引用保存到volatile类型域或者AtomicReference对象中 将对象的引用保存到某个正确构造对象的final类型域中 将对象的引用保存到一个由锁保护的域中

2024-08-24 19:02:50 14

原创 Happens-before 原则(先行发生原则

第一条规则要注意理解,这里只是程序的运行结果看起来像是顺序执行,虽然结果是一样的,但是JVM对没有变量值依赖的操作进行重排序,这个规则只能保证单线程下执行的集群性,不能保证多线程下的集群性。

2024-08-24 19:02:02 126

原创 线程安全性-一致性

在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响单线程程序的执行,而是会影响多线程线程执行的正确性,在Java里,我们可以通过很明显,synchronized和Lock可以保证在同一时间,只有一个线程执行同步代码,实际上是让线程进行同步的执行同步代码,自然就保证了社区性。如果两个操作的执行顺序无法从Happens-在原则中推导出来之前,那么这两个操作就不能保证集群性,虚拟机就可以随意的对它们进行重排序。

2024-08-24 19:01:23 182

翻译 线程安全性

简单介绍一下线程安全性的可见性,可见性是让一个线程对主内存的可以及时的被其他线程修改观察到。Java提供了同步和易失性两种方法来保证可见性。

2024-08-23 07:15:00 31

原创 CAS底层原理

CAS 是如何将这两个操作进行比较和交换,变成一个原子操作呢?这符合硬件指令集的发展,实际上,我们可以使用同步将这两个操作变成原子的,但是对象就没有所以我们依靠硬件来完成,硬件只能保证一个从外观上需要多次操作的行为只需通过一条处理器指令才能完成。

2024-08-23 07:00:00 119

原创 原子性之同步

我们知道原子性提供了互斥访问,同一时刻只能有一个线程来对其进行操作。在Java里能保证同一时刻只有一个线程来对其进行操作的,除了原子包之外,还有锁机制。

2024-08-23 07:00:00 193

翻译 CAS的优点

CAS 看起来非常的吊,但是它仍然有缺点,最顶尖的就是 ABA 问题:在 CAS 操作的时候,其他线程将变量的值 A 改成了 B,然后又改成了 A。本线程使用期望值 A与当前变量进行比较的时候,发现A变量没有变化,于是CAS就将A值进行了交换操作。这个时候实际上A值已经被其他线程改变过,这与设计思想是不符合的。如果只是在基本类型上是没有问题的,但如果是引用类型呢?每次修改就检查版本号,如果版本号变了,说明改过。这样只要变量被某个线程修改过,该变量版本号就会递增发生操作,从而解决了ABA问题。

2024-08-22 11:03:38 12

原创 什么时候适合使用ARM编程

任务会阻塞线程,导致后面的代码无法执行:比如一边从文件中读取,一边进行大量计算的情况 任务执行时间过长,可以划分为分工明确的子任务:比如分段下载 任务间断性执行:日志打印 任务本身需要协作执行:比如生产者消费者问题

2024-08-22 10:59:28 69

原创 先行发生原则happens-before

判断数据是否有竞争、线程是否安全的主要依据。

2024-08-22 10:54:00 107

翻译 线程安全性概述

或者这些进程将如何交替执行,并且在主调代码中。当多个线程访问某个类时,不管运行时环境采用。

2024-08-20 08:45:00 10

翻译 创建线程池的注意事项以及多线程异常处理

创建线程池时,核心线程数不要过大 相应的逻辑,发生异常时要处理 submit:如果发生异常,不会立即抛出,而是在get的时候,再抛出异常 execute:直接抛出异常

2024-08-20 07:45:00 15

原创 尽量避免使用Executor框架创建线程池

允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。允许的请求队列长度为Integer.MAX_VALUE,可能回堆积大量的请求,从而导致OOM。

2024-08-20 07:00:00 177

原创 线程安全性-有序性

在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性 在Java里,我们可以通过volatile关键字保证一定的有序性,另外也可以通过synchronized和Lock来保证有序性。第一条规则要注意理解,这里只是程序的运行结果看起来像是顺序执行,虽然结果是一样的,但JVM会对没有变量值依赖的操作进行重排序,这个规则只能保证单线程下执行的有序性,不能保证多线程下的有序性。

2024-08-20 07:00:00 253

原创 线程池拒绝策略

【代码】线程池拒绝策略。

2024-08-19 07:00:00 108

原创 ThreadPoolExecutor

【代码】ThreadPoolExecutor。

2024-08-19 07:00:00 110

原创 为什么要使用线程池?

诸如 Web 服务器、数据库服务器、文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务。请求以某种方式到达服务器,这种方式可能是通过网络协议(例如 HTTP、FTP )、通过 JMS队列或者可能通过轮询数据库。不管请求如何到达,服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的。每当一个请求到达就创建一个新线程,然后在新线程中为请求服务,但是频繁的创建线程,销毁线程所带来的系统开销其实是非常大的。

2024-08-18 07:15:00 79

翻译 线程池为线程生命周期开销问题和资源不足问题提供了解决方案

通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。

2024-08-18 07:15:00 15

原创 第八章 并发工具类

它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据, 如果第一个线程先执行exchange方法,它会一直等待第二个线程也执行exchange,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。因此使用Exchanger的重点是成对的线程使用exchange()方法,当有一对线程达到了同步点,就会进行交换数据。允许一组线程相互等待达到一个公共的障碍点,之后再继续执行。控制开发数量接口限流。

2024-08-18 07:00:00 142

原创 为什么要使用线程池?

到达请求就创建一个新线程,但是在新线程中为请求服务,中断的创建线程,想想线程所带来的系统开销其实是非常大的。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。而且,通过适当地调整线程池中的线程数量,或者当请求的数量超过某个阈值时,就强制任何新到达的请求一直等待,直到获得一个线程来进行状况处理,从而可以防止资源短缺。使用线程池构建的应用程序很容易遭受任何其他多线程应用程序的所有并发风险,例如同步错误和死锁,它也很容易遭受特定于线程池的少数其他风险,例如与有关的死锁、资源不足和线路中断。

2024-08-17 21:51:02 112

原创 为什么要使用线程池?

到达请求就创建一个新线程,但是在新线程中为请求服务,中断的创建线程,想想线程所带来的系统开销其实是非常大的。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。而且,通过适当地调整线程池中的线程数量,或者当请求的数量超过某个阈值时,就强制任何新到达的请求一直等待,直到获得一个线程来进行状况处理,从而可以防止资源短缺。使用线程池构建的应用程序很容易遭受任何其他多线程应用程序的所有并发风险,例如同步错误和死锁,它也很容易遭受特定于线程池的少数其他风险,例如与有关的死锁、资源不足和线路中断。

2024-08-16 08:00:00 160

原创 LinkedBlockingQueue的使用

直接调用poll,唯一的区别即使remove会发送异常,而poll在队列为空的时候直接返回null。中,LinkedBlockingQueue 使用的非常频繁。阑尾可以作为生产者消费者的中间商。添加注明是offer,区别是在队列满的时候,add会报异常。在队列满的时候,会进入阻塞的状态。在队列为空的时候直接返回null。在队列为空的时候,会进入等待的状态。报价对列如果满了,直接入队失败。

2024-08-16 06:45:00 141

原创 同步容器类的优缺点

使用Iterator迭代容器或使用for-each迭代容器,在迭代过程中容器会抛出ConcurrentModificationException异常想要极避免出现ConcurrentModificationException,就必须在迭代过程中持有容器的。,hashCode,equalse,containsAll,removeAll,retainAll等方法都会隐式的Iterate,也即可能抛出ConcurrentModificationException。但是如果容器增加,则迭代的时间也差不多。

2024-08-16 06:30:00 133

翻译 原子地更新属性

原子地更新某类里的某一个字段时,就需要使用原子地更新字段类,原子包提供了以下4类进行原子地字段更新。使用此类的时候,必须遵循以下原则。

2024-08-15 07:15:00 15

原创 原子更新基本类型

发展至JDk1.8,基本类型原子类有以下几个: AtomicBoolean、AtomicInteger、AtomicLong、DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder 大致可以归为3类。以AtomicInteger为例子的代码。

2024-08-15 06:45:00 697

原创 对于原子类

JDk1.5之后,新增的原子操作类提供了一种简单、性能高效、线程安全地更新一个变量的方式,这些类同样位于JUC包下的原子包下,发展到JDk1.8,该包下共有17个类,涵盖了atomyupdate基本类型、atomyupdate备份、atomyupdate属性、atomyupdate引用。新增的原子类:DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder、Striped64。一度认为原子是不可分割的最小单位,故原子类可以认为其操作都是不可分割的。

2024-08-15 06:30:00 103

翻译 原子性操作

想要从自己的账户中转1000块钱到B的账户里。那个从A开始转帐,到转帐结束这个过程,命名一个事务。* 每次调用对num进行++操作,加上synchronized使得num++操作变成原子操作。一个操作或者多个操作或者全部执行并且执行的过程不会被任何因素打断,或者就都不执行。//每个线程执行完成之后,调用countDownLatch。如何把非原子性操作变成原子性。* 线程不安全操作代码实例。

2024-08-14 22:56:00 14

原创 关于守护线程

不要在守护线程里去进行读写操作、执行计算逻辑。建议:尽量少使用守护线程,智力不可控。* 守护线程Demo。

2024-08-14 22:51:21 129

原创 线程的列表

线程的优先级告诉程序该线程的重要程度有多少。如果有大量线程都被阻塞,都在等待运行,程序会先运行优先级的那个线程。但是,这并不代表优先级较低的线程不会运行。若线程的优先级较低,只是表示它被准许运行的机会小一些。不同的平台,对线程的优先级的支持不同。编程的时候,不要过度依赖线程优先级,如果你的程序运行是否正确取决于你设置的优先级是否按所设置的优先级运行,那样的程序不正确。

2024-08-14 22:48:51 416

翻译 AbstractQueuedSynchronizer浅析

此类通过支持独占模式的子类定义了一个嵌套的 AbstractQueuedSynchronizer.ConditionObject 类,可以将这个类用作 Condition 实现。如果给定保存的状态值,那么 acquire(int) 方法可以将此对象最终恢复为它以前获取的状态。此类的序列化只存储维护状态的基础原子整数,因此已序列化的对象拥有空的线程队列。需要可序列化的典型子类将定义一个 readObject 方法,该方法在反序列化时将此对象恢复到某个已知初始状态。

2024-08-13 21:31:08 14

原创 Lock接口的方法

这个方法暂且不在此讲述,属于线程协作的一部分,后面会讲。方法是用来释放锁的。

2024-08-13 07:19:07 95

原创 关于锁的分类

jvm实现,使线程在没获得锁的时候,不被挂起,转而执行空循环,循环几次之后,如果还没能获得锁,则被挂起。阻塞锁改变了线程的运行状态,让线程进入阻塞状态进行等待,当获得相应的信号(唤醒或者时间)时,才可以进入线程的准备就绪状态,转为就绪状态的所有线程,通过竞争,进入运行状态。总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。偏向锁使用了一种等到竞争出现才释放锁的机制,所以当其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁。

2024-08-13 07:18:00 290

数据库原理学习 (2).zip

数据库原理学习 (2).zip

2024-08-25

gy数据库原理.zip

gy数据库原理.zip

2024-08-22

机器学习入门精选 (2).zip

机器学习入门精选 (2).zip

2024-08-19

学习论文的研写.zip

学习论文的研写.zip

2024-08-19

maya小脚本参考.zip

maya脚本

2024-08-19

Blue-Bridge-Cup-maste2018蓝桥杯VIP题集r (2).zip

Blue-Bridge-Cup-maste2018蓝桥杯VIP题集r (2).zip

2024-08-18

蓝桥杯嵌入式备赛代码学习参考 (2).zip

蓝桥杯嵌入式备赛代码学习参考 (2).zip

2024-08-18

USTC Beamer模板,学校公用ppt模板 (2).zip

USTC Beamer模板,学校公用ppt模板 (2).zip

2024-08-18

数学模型入门基础.zip

数学模型入门基础

2024-08-18

数学模型入门基础 (2).zip

数学模型入门基础 (2)

2024-08-18

2023高教社杯数学建模竞赛题代码 (2).zip

2023高教社杯数学建模竞赛题代码 (2).zip

2024-08-18

impossible的数学建模.zip

impossible的数学建模.zip

2024-08-18

c语言入门全..zip

c语言

2024-08-14

神经网络分类器 (2).zip

神经网络分类器 (2).zip

2024-08-14

计算机二级python试题 (2).zip

计算机二级python试题 (2).zip

2024-08-13

Ai绘画资料合集.zip

Ai绘画资料合集.zip

2024-08-13

常见的各类算法.zip

常见的各类算法.zip

2024-08-13

机器学习相关试题.zip

机器学习相关试题.zip

2024-08-13

嵌入式linux开发教程

嵌入式linux开发教程

2024-08-13

一个简易的gif入门教程

快速入门git,使用gif的方式播放命令行

2024-08-13

Linux-常用命令.zip

linux常用命令

2024-08-13

基于Python的reliability系统 (3).zip

python

2024-08-13

基于Python的reliability系统 (2).zip

基于Python的reliability系统 (2).zip

2024-08-12

基于Python的reliability系统

基于Python的reliability系统

2024-08-12

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除