「java无锁」Java无锁队列

博主:adminadmin 2023-01-05 10:03:09 676

本篇文章给大家谈谈java无锁,以及Java无锁队列对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

java中共享锁与无锁的区别?

独享锁是指该锁一次只能被一个线程所持有。

共享锁是指该锁可被多个线程所持有。

对于Java ReentrantLock而言,其是独享锁。但是对于Lock的另一个实现类ReadWriteLock,其读锁是共享锁,其写锁是独享锁。

读锁的共享锁可保证并发读是非常高效的,读写,写读 ,写写的过程是互斥的。

独享锁与共享锁也是通过AQS来实现的,通过实现不同的方法,来实现独享或者共享。

对于Synchronized而言,当然是独享锁。

java多线程中的死锁,活锁,饥饿,无锁都是什么鬼

死锁发生在当一些进程请求其它进程占有的资源而被阻塞时。

另外一方面,活锁不会被阻塞,而是不停检测一个永远不可能为真的条件。除去进程本身持有的资源外,活锁状态的进程会持续耗费宝贵的CPU时间。

最后,进程会处于饥饿状态是因为持续地有其它优先级更高的进程请求相同的资源。不像死锁或者活锁,饥饿能够被解开。例如,当其它高优先级的进程都终止时并且没有更高优先级的进程到达。

Mark Word

先说一下synchronized的历史吧,在jdk1.6之前synchronized就是单纯一个重量级锁,在jdk1.6的时候,有一个叫Doug Lea的大哥看不过去了,明明很多情况都是不需要重量级锁的,只需要标记一下,所以这个大哥就开发一个ReentrantLock,无竞争的情况在java层面就完成了加锁解锁,这时候吧,jdk可能觉得面子上有点那啥,便开始优化synchronized,然后就产生了我们熟知的偏向锁,轻量级锁,重量级锁。

因为网上大部分的文章写mark word的解释基本都是基于32位jdk,这里我简单介绍一下64位jdk中,mark down的组成,和锁升级过程标志位的变化。

java的对象布局是由对象头、实例数据、数据对齐组成

但实际情况并不一定,后面我们引用下面的maven依赖来进行证明

发现没有数据填充的部分,这时候我们并不需要数据填充

(3)同理,我们将变量a删除后,没有了示例数据这一部分

对齐填充并不是必然存在的,也没有什么特别的意义,他仅仅起着占位符的作用,由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。而对象头正好是8字节的倍数,因此,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。

对象头由两部分组成,一部分用于存储自身的运行时数据,称之为mark word,另外一部分是类型指针,及对象指向它的类元数据的指针。这里我们只研究一下mark word

OpenJdk官网对于mard word的定义

每个对象头的第一个字。通常是一组位字段,包括同步状态和标识哈希码。也可以是指向同步相关信息的指针(具有特征性的低位编码)。在GC期间,可以包含GC状态位。

我们再看hotspot的源码,里面有一段 注释

首先无锁、偏向锁、轻量锁大家应该都很清楚,但是图中的无锁可偏向和无锁不可偏向我在这里解释下,

我们知道偏向锁会在mark word中记录偏向线程的id,但是根据上图,我们可以发现,hashcode和偏向线程的id的位置是有冲突的,所以在不可偏向时就是我们计算了这个类的hashcode,这时候锁会直接升级成轻量级锁,后面我们会通过例子来证明。

这里我要先说明下,后面我们输出的mark word和我们期望的 在位置上是相反的,这是由于cpu的缘故,这里不做解释

jdk8中,有一个偏向锁的延迟开启,我们需要把延迟时间设置为0

-XX:BiasedLockingStartupDelay=0

首先我们可以看到 实例的hashcode和mark word里面标记的一样,并且现在是无锁不可偏向状态

下面不计算hashcode再看一下锁的标志位

java同步锁慢怎么解决

百度知道

java同步锁慢怎么解决

173******87

超过41用户采纳过TA的回答

关注

成为第1位粉丝

性能优化的需求实现中,如果使用了多线程并行来提高程序运行效率,那么一个很难绕开的部分就是同步加锁。同步锁会将多线程并行执行强制合流为串行执行,通常会成为整个程序的性能瓶颈所在,所以锁性能的优化必不可少。一般来说,优化锁性能的关键如下:

降低锁竞争概率

提高锁竞争效率

1. 降低锁竞争概率

1.1 减小锁粒度

要降低锁竞争发生的概率,一个非常直观的思路是减小锁粒度,核心思想是将大的全局锁分割为一个个范围精确的小锁,使线程的竞争对象从全局锁变更为小锁,从而减少锁竞争发生

java并发框架有哪些

Java并发框架java.util.concurrent是JDK5中引入到标准库中的(采用的是Doug

Lea的并发库)。该包下的类可以分为这么块:

Executors

1)接口:

Executor(例子涉及):用来执行提交的Runnable任务的对象。是一个简单的标准化接口,用来定义包括线程池、异步IO、轻量级任务框架等等。任务可以由一个新创建的线程、一个已有任务执行线程、或是线程直接调用execute()来执行,可以串行也可并行执行,取决于使用的是哪个Executor具体类。

ExecutorService(例子涉及):Executor的子接口,提供了一个更加具体的异步任务执行框架:提供了管理结束的方法,以及能够产生Future以跟踪异步任务进程的方法。一个ExcutorService管理着任务队列和任务调度。

ScheduledExecutorService(例子涉及):ExecutorService的子接口,增加了对延迟和定期任务执行的支持。

Callable(例子涉及):一个返回结果或抛出异常的任务,实现类需要实现其中一个没有参数的叫做call的方法。Callabe类似于Runnable,但是Runnable不返回结果且不能抛出checked

exception。ExecutorService提供了安排Callable异步执行的方法。

Future(例子涉及):代表一个异步计算的结果(由于是并发执行,结果可以在一段时间后才计算完成,其名字可能也就是代表这个意思吧),提供了可判断执行是否完成以及取消执行的方法。

2)实现:

ThreadPoolExecutor和ScheduledThreadPoolExecutor:可配置线程池(后者具备延迟或定期调度功能)。

Executors(例子涉及):提供Executor、ExecutorService、ScheduledExecutorService、ThreadFactory以及Callable的工厂方法及工具方法。

FutureTask:对Future的实现

ExecutorCompletionService(例子涉及):帮助协调若干(成组)异步任务的处理。

Queues

非阻塞队列:ConcurrentLinkedQueue类提供了一个高效可伸缩线程安全非阻塞FIFO队列。

阻塞队列:BlockingQueue接口,有五个实现类:LinkedBlockingQueue(例子涉及)、ArrayBlockingQueue、SynchronousQueue、PriorityBlockingQueue和DelayQueue。他们对应了不同的应用环境:生产者/消费者、消息发送、并发任务、以及相关并发设计。

Timing

TimeUnit类(例子涉及):提供了多种时间粒度(包括纳秒)用以表述和控制基于超时的操作。

Synchronizers 提供特定用途同步语境

Semaphore(例子涉及):计数信号量,这是一种经典的并发工具。

CountDownLatch(例子涉及):简单的倒计数同步工具,可以让一个或多个线程等待直到另外一些线程中的一组操作处理完成。

CyclicBarrier(例子涉及):可重置的多路同步工具,可重复使用(CountDownLatch是不能重复使用的)。

Exchanger:允许两个线程在汇合点交换对象,在一些pipeline设计中非常有用。

Concurrent Collections

除队列外,该包还提供了一些为多线程上下文设计的集合实现:ConcurrentHashMap、CopyOnWriteArrayList及CopyOnWriteArraySet。

注意:"Concurrent"前缀的类有别于"synchronized"前缀的类。“concurrent”集合是线程安全的,不需要由单排斥锁控制的(无锁的)。以ConcurrentHashMap为例,允许任何数量的并发读及可调数量的并发写。“Synchronized”类则一般通过一个单锁来防止对集合的所有访问,开销大且伸缩性差。

什么是原子操作,java中的原子操作是什么

"原子操作(atomic operation)是不需要synchronized",所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch;

java中一般事务管理里面用到原子操作。

详细分析如下:

原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分,将整个操作视作一个整体是原子性的核心特征;

使用原子操作的好处:

⑴. 性能角度:它执行多次的所消耗的时间远远小于由于线程所挂起到恢复所消耗的时间,因此无锁的CAS操作在性能上要比同步锁高很多;

⑵. 业务需求:业务本身的需求上,无锁机制本身就可以满足我们绝不多数的需求,并且在性能上也可以大大的进行提升。

例子:我们使用的版本控制工具与之其实非常的相似,如果使用锁来同步,其实就意味着只能同时一个人对该文件进行修改,此时其他人就无法操作文件,如果生活中真正遇到这样的情况我们一定会觉得非常不方便,而现实中我们其实并不是这样,我们大家都可以修改这个文件,只是谁提交的早,那么他就把他的代码成功提交的版本控制服务器上,其实这一步就对应着一个原子操作,而后操作的人往往却因为冲突而导致提交失败,此时他必须重新更新代码进行再次修改,重新提交。

java无锁的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于Java无锁队列、java无锁的信息别忘了在本站进行查找喔。