当前位置: 首页 > news >正文

做个外贸网站一般需要多少钱十大网站建设

做个外贸网站一般需要多少钱,十大网站建设,对电子商务网站建设与管理的心得,广东阳江房产网1、前言 本篇主要基于Java面试题之并发篇#xff08;一#xff09;继续梳理java中关于并发相关的高频面试题。本篇的面试题基于网络整理#xff0c;和自己编辑。在不断的完善补充哦。 2、synchronized 的原理是什么? synchronized是 Java 内置的关键字#xff0c;它提供…1、前言 本篇主要基于Java面试题之并发篇一继续梳理java中关于并发相关的高频面试题。本篇的面试题基于网络整理和自己编辑。在不断的完善补充哦。 2、synchronized 的原理是什么? synchronized是 Java 内置的关键字它提供了一种独占的加锁方式。 synchronized的获取和释放锁由JVM实现用户不需要显示的释放锁非常方便。然而synchronized 也有一定的局限性。当线程尝试获取锁的时候如果获取不到锁会一直阻塞。 如果获取锁的线程进入休眠或者阻塞除非当前线程异常否则其他线程尝试获取锁必须一直等待。 2.1、当一个线程进入某个对象的一个 synchronized 的实例方法后其它线程是否可进入此对象的其它方法 如果其他方法没有 synchronized 的话其他线程是可以进入的。所以要开放一个线程安全的对象时得保证每个方法都是线程安全的。 3、同步方法和同步块哪个是更好的选择 同步块是更好的选择因为它不会锁住整个对象当然你也可以让它锁住整个对象。同步方法会锁住整个对象哪怕这个类中有多个不相关联的同步块这通常会导致他们停止执行并需要等待获得这个对象上的锁。 同步块更要符合开放调用的原则只在需要锁住的代码块锁住相应的对象这样从侧面来说也可以避免死锁。 4、在监视器(Monitor)内部是如何做线程同步的 监视器和锁在 Java 虚拟机中是一块使用的。监视器监视一块同步代码块确保一次只有一个线程执行同步代码块。每一个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码。 5、Java 如何实现“自旋”spin 代码如下 public class SpinLock {private AtomicReferenceThread sign new AtomicReference();public void lock() { // 1Thread current Thread.currentThread();while(!sign .compareAndSet(null, current)) {// 1.1}}public void unlock () { // 2Thread current Thread.currentThread();sign .compareAndSet(current, null);}}1 处#lock() 方法如果获得不到锁就会“死循环”直到或得到锁为止。考虑到“死循环”会持续占用 CPU 可能导致其它线程无法获得到 CPU 执行可以在 1.1 处增加 Thread.yiead() 代码段出让下 CPU 。2 处#unlock() 方法释放锁。 6、volatile 实现原理 6.1、volatile 有什么用 volatile 保证内存可见性和禁止指令重排。 同时volatile 可以提供部分原子性。 简单来说volatile 用于多线程环境下的单次操作(单次读或者单次写)。 6.2、volatile 变量和 atomic 变量有什么不同 volatile 变量可以确保先行关系即写操作会发生在后续的读操作之前但它并不能保证原子性。例如用 volatile 修饰 count 变量那么 count 操作就不是原子性的。AtomicInteger 类提供的 atomic 方法可以让这种操作具有原子性。例如 #getAndIncrement() 方法会原子性的进行增量操作把当前值加一其它数据类型和引用变量也可以进行相似操作。 6.3、可以创建 volatile 数组吗? Java 中可以创建 volatile 类型数组不过只是一个指向数组的引用而不是整个数组。如果改变引用指向的数组将会受到 volatile 的保护但是如果多个线程同时改变数组的元素volatile 标示符就不能起到之前的保护作用了。 同理对于 Java POJO 类使用 volatile 修饰只能保证这个引用的可见性不能保证其内部的属性。 6.4、volatile 能使得一个非原子操作变成原子操作吗? 一个典型的例子是在类中有一个 long 类型的成员变量。如果你知道该成员变量会被多个线程访问如计数器、价格等你最好是将其设置为 volatile 。为什么因为 Java 中读取 long 类型变量不是原子的需要分成两步如果一个线程正在修改该 long 变量的值另一个线程可能只能看到该值的一半前 32 位。但是对一个 volatile 型的 long 或 double 变量的读写是原子。 6.5、volatile 类型变量提供什么保证 volatile 主要有两方面的作用 避免指令重排可见性保证 例如JVM 或者 JIT 为了获得更好的性能会对语句重排序但是 volatile 类型变量即使在没有同步块的情况下赋值也不会与其他语句重排序。 volatile 提供 happens-before 的保证确保一个线程的修改能对其他线程是可见的。某些情况下volatile 还能提供原子性如读 64 位数据类型像 long 和 double 都不是原子的(低 32 位和高 32 位)但 volatile 类型的 double 和 long 就是原子的。不过需要在 64 位的 JVM 虚拟机上。 6.6、volatile 和 synchronized 的区别 volatile 本质是在告诉 JVM 当前变量在寄存器工作内存中的值是不确定的需要从主存中读取。synchronized 则是锁定当前变量只有当前线程可以访问该变量其他线程被阻塞住。volatile 仅能使用在变量级别。synchronized 则可以使用在变量、方法、和类级别的。volatile 仅能实现变量的修改可见性不能保证原子性。而synchronized 则可以保证变量的修改可见性和原子性。volatile 不会造成线程的阻塞。synchronized 可能会造成线程的阻塞。volatile 标记的变量不会被编译器优化。synchronized标记的变量可以被编译器优化。 另外会有面试官会问 volatile 能否取代 synchronized 呢答案肯定是不能虽然说 volatile 被称之为轻量级锁但是和 synchronized 是有本质上的区别原因就是上面的几点落。 6.7、什么场景下可以使用 volatile 替换 synchronized  只需要保证共享资源的可见性的时候可以使用 volatile 替代synchronized 保证可操作的原子性一致性和可见性。volatile 适用于新值不依赖于旧值的情形。1 写 N 读。不与其他变量构成不变性条件时候使用 volatile 。 7、什么是死锁、活锁 死锁是指两个或两个以上的进程或线程在执行过程中因争夺资源而造成的一种互相等待的现象若无外力作用它们都将无法推进下去。 7.1、产生死锁的必要条件 互斥条件所谓互斥就是进程在某一时间内独占资源。请求与保持条件一个进程因请求资源而阻塞时对已获得的资源保持不放。不剥夺条件进程已获得资源在末使用完之前不能强行剥夺。循环等待条件若干进程之间形成一种头尾相接的循环等待资源关系。 7.2、死锁的解决方法 撤消陷于死锁的全部进程。逐个撤消陷于死锁的进程直到死锁不存在。从陷于死锁的进程中逐个强迫放弃所占用的资源直至死锁消失。从另外一些进程那里强行剥夺足够数量的资源分配给死锁进程以解除死锁状态。 7.3、什么是活锁 活锁任务或者执行者没有被阻塞由于某些条件没有满足导致一直重复尝试失败尝试失败。 7.4、死锁与活锁的区别 活锁和死锁的区别在于处于活锁的实体是在不断的改变状态所谓的“活”而处于死锁的实体表现为等待活锁有可能自行解开死锁则不能。 实际上死锁就是悲观锁可能产生的结果而活锁是乐观锁可能产生的结果。 8、什么是悲观锁、乐观锁 8.1、悲观锁 悲观锁总是假设最坏的情况每次去拿数据的时候都认为别人会修改所以每次在拿数据的时候都会上锁这样别人想拿这个数据就会阻塞直到它拿到锁。 传统的关系型数据库里边就用到了很多这种锁机制比如行锁表锁等读锁写锁等都是在做操作之前先上锁。再比如 Java 里面的同步原语 synchronized 关键字的实现也是悲观锁。 8.2、乐观锁 乐观锁顾名思义就是很乐观每次去拿数据的时候都认为别人不会修改所以不会上锁但是在更新的时候会判断一下在此期间别人有没有去更新这个数据可以使用版本号等机制。乐观锁适用于多读的应用类型这样可以提高吞吐量。 像数据库提供的类似于 write_condition 机制其实都是提供的乐观锁。 例如version 字段比较跟上一次的版本号如果一样则更新如果失败则要重复读-比较-写的操作 在 Java 中 java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的。 8.3、乐观锁的实现方式 使用版本标识来确定读到的数据与提交时的数据是否一致。提交后修改版本标识不一致时可以采取丢弃和再次尝试的策略。Java 中的 Compare and Swap 即 CAS 当多个线程尝试使用 CAS 同时更新同一个变量时只有其中一个线程能更新变量的值而其它线程都失败失败的线程并不会被挂起而是被告知这次竞争中失败并可以再次尝试。 9、Java AQS java.util.concurrent.locks.AbstractQueuedSynchronizer 抽象类简称 AQS 是一个用于构建锁和同步容器的同步器。事实上concurrent 包内许多类都是基于 AQS 构建。例如 ReentrantLockSemaphoreCountDownLatchReentrantReadWriteLock等。AQS 解决了在实现同步容器时设计的大量细节问题。 AQS 使用一个 FIFO 的队列表示排队等待锁的线程队列头节点称作“哨兵节点”或者“哑节点”它不与任何线程关联。其他的节点与等待线程关联每个节点维护一个等待状态 waitStatus 。 10、什么是 Java Lock 接口 java.util.concurrent.locks.Lock 接口比 synchronized 提供更具拓展行的锁操作。它允许更灵活的结构可以具有完全不同的性质并且可以支持多个相关类的条件对象。它的优势有 可以使锁更公平。可以使线程在等待锁的时候响应中断。可以让线程尝试获取锁并在无法获取锁的时候立即返回或者等待一段时间。可以在不同的范围以不同的顺序获取和释放锁。 11、什么是可重入锁ReentrantLock 举例来说明锁的可重入性。代码如下 public class UnReentrant{Lock lock new Lock();public void outer() {lock.lock();inner();lock.unlock();}public void inner() {lock.lock();//do somethinglock.unlock();}} #outer() 方法中调用了 #inner() 方法#outer() 方法先锁住了 lock 这样 #inner() 就不能再获取 lock 。其实调用 #outer() 方法的线程已经获取了 lock 锁但是不能在 #inner() 方法中重复利用已经获取的锁资源这种锁即称之为不可重入。可重入就意味着线程可以进入任何一个它已经拥有的锁所同步着的代码块。 synchronized、ReentrantLock 都是可重入的锁可重入锁相对来说简化了并发编程的开发。 简单来说ReenTrantLock 的实现是一种自旋锁通过循环调用 CAS 操作来实现加锁。它的性能比较好也是因为避免了使线程进入内核态的阻塞状态。想尽办法避免线程进入内核的阻塞状态是我们去分析和理解锁设计的关键钥匙。 12、synchronized 和 ReentrantLock 异同 12.1、相同点 都实现了多线程同步和内存可见性语义。都是可重入锁。 12.2、不同点 1、同步实现机制不同 synchronized 通过 Java 对象头锁标记和 Monitor 对象实现同步。 ReentrantLock 通过CAS、AQSAbstractQueuedSynchronizer和 LockSupport用于阻塞和解除阻塞实现同步。   2、可见性实现机制不同 synchronized 依赖 JVM 内存模型保证包含共享变量的多线程内存可见性。 ReentrantLock 通过 ASQ 的 volatile state 保证包含共享变量的多线程内存可见性。 3、使用方式不同 synchronized 可以修饰实例方法锁住实例对象、静态方法锁住类对象、代码块显示指定锁对象。 ReentrantLock 显示调用 tryLock 和 lock 方法需要在 finally 块中释放锁。 4、功能丰富程度不同 synchronized 不可设置等待时间、不可被中断interrupted。 ReentrantLock 提供有限时间等候锁设置过期时间、可中断锁lockInterruptibly、condition提供 await、condition提供 await、signal 等方法等丰富功能 5、锁类型不同 synchronized 只支持非公平锁。 ReentrantLock 提供公平锁和非公平锁实现。当然在大部分情况下非公平锁是高效的选择。 在 synchronized 优化以前它的性能是比 ReenTrantLock 差很多的但是自从 synchronized 引入了偏向锁轻量级锁自旋锁后两者的性能就差不多了在两种方法都可用的情况下官方甚至建议使用 synchronized 。 并且实际代码实战中可能的优化场景是通过读写分离进一步性能的提升所以使用 ReentrantReadWriteLock 。 13、ReadWriteLock 是什么 ReadWriteLock 读写锁是用来提升并发程序性能的锁分离技术的 Lock 实现类。可以用于 “多读少写” 的场景读写锁支持多个读操作并发执行写操作只能由一个线程来操作。 ReadWriteLock 对向数据结构相对不频繁地写入但是有多个任务要经常读取这个数据结构的这类情况进行了优化。ReadWriteLock 使得你可以同时有多个读取者只要它们都不试图写入即可。如果写锁已经被其他任务持有那么任何读取者都不能访问直至这个写锁被释放为止。 ReadWriteLock 对程序性能的提高主要受制于如下几个因素 数据被读取的频率与被修改的频率相比较的结果。读取和写入的时间有多少线程竞争是否在多处理机器上运行 14、Condition 是什么 在没有 Lock 之前我们使用 synchronized 来控制同步配合 Object 的 #wait()、#notify() 等一系列方法可以实现等待 / 通知模式。在 Java SE 5 后Java 提供了 Lock 接口相对于 synchronized 而言Lock 提供了条件 Condition 对线程的等待、唤醒操作更加详细和灵活。 15、LockSupport 是什么 LockSupport 是 JDK 中比较底层的类用来创建锁和其他同步工具类的基本线程阻塞。 Java 锁和同步器框架的核心 AQS(AbstractQueuedSynchronizer)就是通过调用 LockSupport#park()和 LockSupport#unpark() 方法来实现线程的阻塞和唤醒的。LockSupport 很类似于二元信号量(只有 1 个许可证可供使用)如果这个许可还没有被占用当前线程获取许可并继续执行如果许可已经被占用当前线程阻塞等待获取许可。 17、Java 内存模型 17.1、什么是 Java 内存模型 Java 虚拟机规范中试图定义一种 Java 内存模型Java Memory ModelJMM来屏蔽掉各层硬件和操作系统的内存访问差异以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。 Java 内存模型规定了所有的变量都存储在主内存Main Memory中。每条线程还有自己的工作内存Working Memory线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝线程对变量的所有操作读取、赋值等都必须在工作内存中进行而不能直接读写主内存中的变量。不同的线程之间也无法直接访问对方工作内存中的变量线程间的变量值的传递均需要通过主内存来完成线程、主内存、工作内存三者的关系如下图 线程、主内存、工作内存 18、两个线程之间是如何通信的呢 线程之间的通信方式目前有共享内存和消息传递两种。 18.1、共享内存 在共享内存的并发模型里线程之间共享程序的公共状态线程之间通过写-读内存中的公共状态来隐式进行通信。典型的共享内存通信方式就是通过共享对象进行通信。 例如上图线程 A 与 线程 B 之间如果要通信的话那么就必须经历下面两个步骤 首先线程 A 把本地内存 A 更新过得共享变量刷新到主内存中去。然后线程 B 到主内存中去读取线程 A 之前更新过的共享变量。 18.2、消息传递 在消息传递的并发模型里线程之间没有公共状态线程之间必须通过明确的发送消息来显式进行通信。在 Java 中典型的消息传递方式就是 #wait() 和 #notify() 或者 BlockingQueue 。 19、为什么代码会重排序 在执行程序时为了提供性能处理器和编译器常常会对指令进行重排序但是不能随意重排序不是你想怎么排序就怎么排序它需要满足以下两个条件 在单线程环境下不能改变程序运行的结果。存在数据依赖关系的不允许重排序 需要注意的是重排序不会影响单线程环境的执行结果但是会破坏多线程的执行语义。 20、什么是内存屏障 内存屏障又称内存栅栏是一组处理器指令用于实现对内存操作的顺序限制。 20.1、内存屏障为何重要 对主存的一次访问一般花费硬件的数百次时钟周期。处理器通过缓存caching能够从数量级上降低内存延迟的成本这些缓存为了性能重新排列待定内存操作的顺序。也就是说程序的读写操作不一定会按照它要求处理器的顺序执行。当数据是不可变的同时/或者数据限制在线程范围内这些优化是无害的。如果把这些优化与对称多处理symmetric multi-processing和共享可变状态shared mutable state结合那么就是一场噩梦。 当基于共享可变状态的内存操作被重新排序时程序可能行为不定。一个线程写入的数据可能被其他线程可见原因是数据写入的顺序不一致。适当的放置内存屏障通过强制处理器顺序执行待定的内存操作来避免这个问题。 21、Java 并发容器 21.1、什么是并发容器的实现 何为同步容器可以简单地理解为通过 synchronized来实现同步的容器如果有多个线程调用同步容器的方法它们将会串行执行。 比如 VectorHashtable以及 Collections#synchronizedSet()Collections#synchronizedList() 等方法返回的容器。可以通过查看 VectorHashtable 等这些同步容器的实现代码可以看到这些容器实现线程安全的方式就是将它们的状态封装起来并在需要同步的方法上加上关键字 synchronized 。 并发容器使用了与同步容器完全不同的加锁策略来提供更高的并发性和伸缩性。 例如在 ConcurrentHashMap 中采用了一种粒度更细的加锁机制可以称为分段锁。在这种锁机制下允许任意数量的读线程并发地访问 map 并且执行读操作的线程和写操作的线程也可以并发的访问 map 同时允许一定数量的写操作线程并发地修改 map 所以它可以在并发环境下实现更高的吞吐量。再例如CopyOnWriteArrayList 。 22、SynchronizedMap 和 ConcurrentHashMap 有什么区别 22.1、SynchronizedMap 一次锁住整张表来保证线程安全所以每次只能有一个线程来访为 map 。 22.2、ConcurrentHashMap 使用分段锁来保证在多线程下的性能。ConcurrentHashMap 中则是一次锁住一个桶。ConcurrentHashMap 默认将 hash 表分为 16 个桶诸如 get,put,remove 等常用操作只锁当前需要用到的桶。这样原来只能一个线程进入现在却能同时有 16 个写线程执行并发性能的提升是显而易见的。【注意这块是 JDK7 的实现。在 JDK8 中具体的实现已经改变】 另外 ConcurrentHashMap 使用了一种不同的迭代方式。在这种迭代方式中当 iterator 被创建后集合再发生改变就不再是抛出 ConcurrentModificationException 异常取而代之的是在改变时 new 新的数据从而不影响原有的数据iterator 完成后再将头指针替换为新的数据 这样 iterator 线程可以使用原来老的数据而写线程也可以并发的完成改变。 23、Java 中 ConcurrentHashMap 的并发度是什么 在 JDK8 前ConcurrentHashMap 把实际 map 划分成若干部分来实现它的可扩展性和线程安全。这种划分是使用并发度获得的它是 ConcurrentHashMap 类构造函数的一个可选参数默认值为 16 这样在多线程情况下就能避免争用。 在 JDK8 后它摒弃了 Segment锁段的概念而是启用了一种全新的方式实现利用 CAS 算法。同时加入了更多的辅助变量来提高并发度具体内容还是查看源码吧。 24、ConcurrentHashMap 为何读不用加锁 24.1、在 JDK7 以及以前 HashEntry 中的 key、hash、next 均为 final 型只能表头插入、删除结点。 HashEntry 类的 value 域被声明为 volatile 型。不允许用 null 作为键和值当读线程读到某个 HashEntry 的 value 域的值为 null 时便知道产生了冲突——发生了重排序现象put 方法设置新 value 对象的字节码指令重排序需要加锁后重新读入这个 value 值。volatile 变量 count 协调读写线程之间的内存可见性写操作后修改 count 读操作先读 count根据 happen-before 传递性原则写操作的修改读操作能够看到。 24.1、在 JDK8 开始 Node 的 val 和 next 均为 volatile 型。#tabAt(..,) 和 #casTabAt(...) 对应的 Unsafe 操作实现了 volatile 语义。 25、CopyOnWriteArrayList 可以用于什么应用场景 CopyOnWriteArrayList(免锁容器)的好处之一是当多个迭代器同时遍历和修改这个列表时不会抛出ConcurrentModificationException 异常。在 CopyOnWriteArrayList 中写入将导致创建整个底层数组的副本而源数组将保留在原地使得复制的数组在被修改时读取操作可以安全地执行。 由于写操作的时候需要拷贝数组会消耗内存如果原数组的内容比较多的情况下可能导致 ygc 或者 fgc 。不能用于实时读的场景像拷贝数组、新增元素都需要时间所以调用一个 set 操作后读取到数据可能还是旧的,虽然 CopyOnWriteArrayList 能做到最终一致性,但是还是没法满足实时性要求。 CopyOnWriteArrayList 透露的思想 读写分离读和写分开最终一致性使用另外开辟空间的思路来解决并发冲突 CopyOnWriteArrayList 适用于读操作远远多于写操作的场景。例如缓存。 26、Java 阻塞队列 26.1、什么是阻塞队列有什么适用场景 阻塞队列BlockingQueue是一个支持两个附加操作的队列。这两个附加的操作是 在队列为空时获取元素的线程会等待队列变为非空。当队列满时存储元素的线程会等待队列可用。 阻塞队列常用于生产者和消费者的场景 生产者是往队列里添加元素的线程消费者是从队列里拿元素的线程阻塞队列就是生产者存放元素的容器而消费者也只从容器里拿元素。 BlockingQueue 接口是 Queue 的子接口它的主要用途并不是作为容器而是作为线程同步的的工具因此他具有一个很明显的特性 当生产者线程试图向 BlockingQueue 放入元素时如果队列已满则线程被阻塞。当消费者线程试图从中取出一个元素时如果队列为空则该线程会被阻塞。正是因为它所具有这个特性所以在程序中多个线程交替向BlockingQueue中 放入元素取出元素它可以很好的控制线程之间的通信。 阻塞队列使用最经典的场景就是 Socket 客户端数据的读取和解析 读取数据的线程不断将数据放入队列。然后解析线程不断从队列取数据解析。 26.2、Java 提供了哪些阻塞队列的实现 JDK7 提供了 7 个阻塞队列。分别是 Java5 之前实现同步存取时可以使用普通的一个集合然后在使用线程的协作和线程同步可以实现生产者消费者模式主要的技术就是用好 wait、notify、notifyAll、sychronized 这些关键字。 而在 Java5 之后可以使用阻塞队列来实现此方式大大简少了代码量使得多线程编程更加容易安全方面也有保障。 ArrayBlockingQueue 一个由数组结构组成的有界阻塞队列。 此队列按照先进先出FIFO的原则对元素进行排序但是默认情况下不保证线程公平的访问队列即如果队列满了那么被阻塞在外面的线程对队列访问的顺序是不能保证线程公平即先阻塞先插入的。 LinkedBlockingQueue 一个由链表结构组成的有界阻塞队列。 此队列按照先出先进的原则对元素进行排序 PriorityBlockingQueue 一个支持优先级排序的无界阻塞队列。 DelayQueue支持延时获取元素的无界阻塞队列即可以指定多久才能从队列中获取当前元素。 SynchronousQueue一个不存储元素的阻塞队列。 每一个 put 必须等待一个 take 操作否则不能继续添加元素。并且他支持公平访问队列。 LinkedTransferQueue一个由链表结构组成的无界阻塞队列。 相对于其他阻塞队列多了 tryTransfer 和 transfer 方法。 transfer 方法如果当前有消费者正在等待接收元素take 或者待时间限制的 poll 方法transfer 可以把生产者传入的元素立刻传给消费者。如果没有消费者等待接收元素则将元素放在队列的 tail 节点并等到该元素被消费者消费了才返回。tryTransfer 方法用来试探生产者传入的元素能否直接传给消费者。如果没有消费者在等待则返回 false 。和上述方法的区别是该方法无论消费者是否接收方法立即返回。而 transfer 方法是必须等到消费者消费了才返回。 LinkedBlockingDeque一个由链表结构组成的双向阻塞队列。 优势在于多线程入队时减少一半的竞争。​​ 26.3、阻塞队列提供哪些重要方法 方法处理方式抛出异常返回特殊值一直阻塞超时退出插入方法add(e)offer(e)put(e)offer(e, time, unit)移除方法remove()poll()take()poll(time, unit)检查方法element()peek()不可用不可用 26.4、ArrayBlockingQueue 与 LinkedBlockingQueue 的区别 Queue阻塞与否是否有界线程安全保障适用场景注意事项ArrayBlockingQueue阻塞有界一把全局锁生产消费模型平衡两边处理速度用于存储队列元素的存储空间是预先分配的使用过程中内存开销较小无须动态申请存储空间LinkedBlockingQueue阻塞可配置存取采用 2 把锁生产消费模型平衡两边处理速度无界的时候注意内存溢出问题用于存储队列元素的存储空间是在其使用过程中动态分配的因此它可能会增加 JVM 垃圾回收的负担。 27、延迟队列的实现方式DelayQueue 和时间轮算法的异同 JDK 的 Timer 和 DelayQueue 插入和删除操作的平均时间复杂度为 O(nlog(n)) 而基于时间轮可以将插入和删除操作的时间复杂度都降为 O(1) 。 28、简述 ConcurrentLinkedQueue 和 LinkedBlockingQueue 的用处和不同之处 在 Java 多线程应用中队列的使用率很高多数生产消费模型的首选数据结构就是队列(先进先出)。 Java 提供的线程安全的 Queue 可以分为 1、阻塞队列典型例子是 LinkedBlockingQueue 。 适用阻塞队列的好处多线程操作共同的队列时不需要额外的同步另外就是队列会自动平衡负载即那边生产与消费两边处理快了就会被阻塞掉从而减少两边的处理速度差距。 2、非阻塞队列典型例子是 ConcurrentLinkedQueue 。 当许多线程共享访问一个公共集合时ConcurrentLinkedQueue 是一个恰当的选择。 具体的选择如下 LinkedBlockingQueue 多用于任务队列。 单生产者单消费者多生产者单消费者 ConcurrentLinkedQueue 多用于消息队列。 单生产者多消费者多生产者多消费者 29、Java 原子操作类 29.1、什么是原子操作 原子操作Atomic Operation意为”不可被中断的一个或一系列操作”。 处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操作。在 Java 中可以通过锁和循环 CAS 的方式来实现原子操作。CAS操作 —— Compare Set 或是 Compare Swap 现在几乎所有的 CPU 指令都支持 CAS 的原子操作。 原子操作是指一个不受其他操作影响的操作任务单元。原子操作是在多线程环境下避免数据不一致必须的手段。 int 并不是一个原子操作所以当一个线程读取它的值并加 1 时另外一个线程有可能会读到之前的值这就会引发错误。为了解决这个问题必须保证增加操作是原子的在 JDK5 之前我们可以使用同步技术来做到这一点。到 JDK5 后java.util.concurrent.atomic 包提供了 int 和 long 类型的原子包装类它们可以自动的保证对于他们的操作是原子的并且不需要使用同步。 java.util.concurrent 这个包里面提供了一组原子类。其基本的特性就是在多线程环境下当有多个线程同时执行这些类的实例包含的方法时具有排他性即当某个线程进入方法执行其中的指令时不会被其他线程打断而别的线程就像自旋锁一样一直等到该方法执行完成才由 JVM 从等待队列中选择一个另一个线程进入这只是一种逻辑上的理解。 原子类AtomicBooleanAtomicIntegerAtomicLongAtomicReference 。原子数组AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray 。原子属性更新器AtomicLongFieldUpdaterAtomicIntegerFieldUpdaterAtomicReferenceFieldUpdater 。解决 ABA 问题的原子类AtomicMarkableReference通过引入一个boolean 来反映中间有没有变过AtomicStampedReference通过引入一个 int 来累加来反映中间有没有变过。 30、CAS 操作有什么缺点 30.1、ABA 问题 比如说一个线程 one 从内存位置 V 中取出 A 这时候另一个线程 two 也从内存中取出 A 并且 two 进行了一些操作变成了 B 然后 two 又将 V 位置的数据变成 A 这时候线程 one 进行 CAS 操作发现内存中仍然是 A 然后 one 操作成功。尽管线程 one 的 CAS 操作成功但可能存在潜藏的问题。 从 Java5 开始 JDK 的 atomic包里提供了一个类 AtomicStampedReference 来解决 ABA 问题。 30.2、循环时间长开销大 对于资源竞争严重线程冲突严重的情况CAS 自旋的概率会比较大从而浪费更多的 CPU 资源效率低于 synchronized 。 30.3、只能保证一个共享变量的原子操作 当对一个共享变量执行操作时我们可以使用循环 CAS 的方式来保证原子操作但是对多个共享变量操作时循环 CAS 就无法保证操作的原子性这个时候就可以用锁。 31、总结 本篇文章梳理了java并发相关高频的面试题希望对你有帮助哦。 JAVA面试题传送门 Java面试题之集合篇 Java面试题之并发篇一
http://www.pierceye.com/news/162830/

相关文章:

  • 笑话小网站模板html网站制作标准
  • 大连网站建设哪家专业图片识别搜索引擎
  • 营销网站制作企业邓州市建设局网站
  • 如何从客户网站开发客户请解释网站开发的主要流程.
  • 做网站的价格 外贸最好科技广州网站建设
  • 烟台开发区网站做网站诊断步骤
  • 成都网站建设哪家技术好关于做网站的搞笑段子
  • 网站的设计制作流程计算机网站开发要考什么证
  • 个人域名 公司网站百度推广和网站建设
  • 哪里有做网站服务抖音开放平台是什么
  • 公司网站上传不了图片建设网站条件
  • 精美公司网站源码婚礼策划网站设计
  • 线上设计师网站网络维护是什么意思
  • 培训网站建设阿里云如何建设网站
  • 手机网站列表模板做一钓鱼网站吗
  • 太原网站建设方案策划请问有重庆有做网站吗
  • 网站备案购买语音网站怎么做
  • ftp上传文件到网站深圳成品网站超市
  • 网站开发时app打开很慢建设网站还要云服务器吗
  • 网站设计方案应该怎么做网站自适应开发
  • 徐州手机网站设计青龙县建设局网站
  • 罗湖网站建设费用帮忙做文档的网站
  • 如何在720云网站做全景视频域名注册网站查询工具
  • 网站定制开发流程和功能wordpress怎么看访问
  • 浙江省互联网建设网站python开发手机网站开发
  • 做网站需要多少钱一年动漫制作技术是学什么
  • 刘洋网站建设 够完美保卫处网站建设
  • 个人怎么申请营业执照北京朝阳区优化
  • 免费的舆情网站不用下载直接打开江西城乡建设网站
  • 那些网站是做金融行业网站主目录权限配置