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

筑云网站投诉改变网站的域名空间

筑云网站投诉,改变网站的域名空间,网页设计ai,北京有限公司java后端面试题大全 1.JUC1.1 ReentrantLock(可重入独占式锁)#xff08;难度#xff1a;★★★ 频率#xff1a;★★#xff09;1.2 ReentrantLock比synchronized的优点#xff08;难度#xff1a;★★★ 频率#xff1a;★★#xff09;1.3 CAS的原理和优缺点1.4 syn… java后端面试题大全 1.JUC1.1 ReentrantLock(可重入独占式锁)难度★★★ 频率★★1.2 ReentrantLock比synchronized的优点难度★★★ 频率★★1.3 CAS的原理和优缺点1.4 synchronized与Lock的区别难度★★ 频率★★★★1.5 常用的原子类有哪些, 它们是如何保证原子性的? 1.JUC JUC指的是Java Util Concurrent(java工具中的并发工具), 是 Java SE 5.0 版本之后引入的一个用于支持并发编程的扩展包。 JUC 提供了一组强大的工具和框架用于更方便、更安全地处理多线程编程的问题。 Executor 框架 提供了一套用于管理线程池的接口和类例如 ExecutorService、ThreadPoolExecutor 等用于简化多线程任务的管理和执行。并发集合类 提供了一些线程安全的集合类例如 ConcurrentHashMap、ConcurrentLinkedQueue 等用于在多线程环境下安全地操作集合Lock 框架 引入了显式的锁机制例如 ReentrantLock允许更灵活地进行同步操作。Atomic 变量 提供了一系列原子变量类如 AtomicInteger、AtomicLong用于在没有锁的情况下进行原子性操作。并发工具类 包括 CountDownLatch、CyclicBarrier、Semaphore 等用于协调多个线程的执行。Fork/Join 框架 提供了一种用于并行计算的框架用于处理任务的分解和合并。并发设计模式 提供了一些支持并发编程的设计模式例如生产者-消费者模式、读写锁等。 1.1 ReentrantLock(可重入独占式锁)难度★★★ 频率★★ 它实现了 Lock 接口。与传统的 synchronized 关键字相比ReentrantLock 提供了更多的灵活性和功能。 可重入性Reentrant 同一个线程在持有锁的情况下可以再次获取该锁而不会发生死锁公平性 多个线程竞争同一个锁时这些线程能否按照它们发出请求的顺序获得锁条件变量 提供了与锁关联的 Condition 对象可以用于实现更复杂的线程间协调。 1.可重入性 ReentrantLock 的可重入性体现在同一个线程可以多次获得同一个锁而不会发生死锁。这是通过内部维护一个持有锁的线程计数器来实现的。 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockReentrancyExample {private final Lock lock new ReentrantLock();public void outerMethod() {lock.lock(); // 第一次获得锁try {innerMethod(); // 在同一线程中调用另一个方法再次获得锁} finally {lock.unlock(); // 第一次释放锁}}public void innerMethod() {lock.lock(); // 第二次获得锁try {// 执行需要同步的代码块System.out.println(线程 Thread.currentThread().getName() 获得锁);} finally {lock.unlock(); // 第二次释放锁System.out.println(线程 Thread.currentThread().getName() 释放锁);}}public static void main(String[] args) {ReentrantLockReentrancyExample example new ReentrantLockReentrancyExample();// 启动一个线程调用 outerMethod 方法new Thread(() - {example.outerMethod();}).start();} }outerMethod 方法中调用了 innerMethod 方法而这两个方法都在同一个线程中执行。当线程首次进入 outerMethod 时它成功获得了锁并在 innerMethod 中再次成功获得了同一个锁。在 innerMethod 中释放锁时锁的计数器减为零才真正释放了锁。这种方式确保了同一线程可以在持有锁的情况下多次进入同一个锁保护的代码块。 我们看下执行流程: 线程进入outerMethod获取锁。调用innerMethod在同一线程中再次获取锁。innerMethod执行完毕后释放锁但锁仍然保持在outerMethod中。outerMethod执行完毕后释放锁此时其他线程有机会获取锁。 什么场景下,会使用到锁的可重入性 递归调用 当一个方法递归调用自身并且这个方法是在持有锁的情况下调用的可重入性允许同一个线程在递归调用中多次获取相同的锁而不会发生死锁。 public class RecursiveExample {private final Object lock new Object();public void recursiveMethod(int count) {synchronized (lock) {if (count 0) {System.out.println(Count: count);recursiveMethod(count - 1); // 递归调用再次获取相同锁}}}public static void main(String[] args) {RecursiveExample example new RecursiveExample();example.recursiveMethod(3);} }嵌套调用 当一个方法调用了另一个方法而这两个方法都需要获取相同的锁时可重入性使得同一个线程可以在嵌套调用中多次获取相同的锁。 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class NestedCallExample {private final Lock lock new ReentrantLock();public void outerMethod() {lock.lock(); // 第一次获得锁try {System.out.println(执行 outerMethod);innerMethod(); // 在同一线程中再次获取相同锁} finally {lock.unlock(); // 第一次释放锁}}public void innerMethod() {lock.lock(); // 第二次获得锁try {System.out.println(执行 innerMethod);} finally {lock.unlock(); // 第二次释放锁}}public static void main(String[] args) {NestedCallExample example new NestedCallExample();example.outerMethod();} }二、公平性 公平锁 一个公平的锁会按照请求锁的顺序逐个地授予等待的线程确保所有线程都有机会获得锁避免饥饿某个线程一直无法获取锁的情况 ReentrantLock fairLock new ReentrantLock(true); // 公平锁非公平锁 在一个非公平的锁中当锁可用时系统会任意选择一个等待的线程赋予锁而不考虑等待的时间或请求的顺序。这可能导致某些线程一直无法获得锁从而引发饥饿问题 ReentrantLock unfairLock new ReentrantLock(false); // 非公平锁需要注意的是虽然公平锁确保了锁的公平性但在高并发环境下公平锁的性能可能相对较低因为每次都要考虑等待队列中线程的顺序。非公平锁可能会在性能上有一些优势但可能导致某些线程长时间无法获得锁。 在实际应用中一般情况下会使用非公平锁因为在高并发的情况下公平锁可能会导致线程频繁切换影响性能。非公平锁虽然在一些情况下可能会引入不公平的竞争但能够更好地提高并发性能。选择使用公平锁还是非公平锁需要根据具体的业务场景和性能需求来权衡。 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class FairnessExample {private static final int THREAD_COUNT 5;private static final Lock fairLock new ReentrantLock(true); // 公平锁private static final Lock unfairLock new ReentrantLock(false); // 非公平锁private static void performTask(Lock lock, String lockType) {for (int i 0; i 3; i) {lock.lock();try {System.out.println(Thread Thread.currentThread().getName() acquired lockType lock, counter: i);} finally {lock.unlock();}}}public static void main(String[] args) {// 使用公平锁for (int i 0; i THREAD_COUNT; i) {new Thread(() - performTask(fairLock, fair)).start();}// 使用非公平锁for (int i 0; i THREAD_COUNT; i) {new Thread(() - performTask(unfairLock, unfair)).start();}} }在上述示例中创建了两个 ReentrantLock一个是公平锁一个是非公平锁。在 performTask 方法中线程通过 lock() 方法获取锁执行一些操作然后通过 unlock() 方法释放锁。运行这个程序你会观察到使用公平锁时线程按照请求锁的顺序获取锁而使用非公平锁时线程可能会插队成功不按照请求的顺序获取锁。这是通过 ReentrantLock 的公平性来体现的。 1.2 ReentrantLock比synchronized的优点难度★★★ 频率★★ 1.可中断性 可中断性是指在一个线程等待获取锁的过程中如果其他线程对该等待线程进行中断调用 interrupt() 方法那么等待线程能够感知到中断并有机会响应中断而不是一直等待下去。在这种情况下等待线程会收到 InterruptedException 异常。 在使用 ReentrantLock 的 lockInterruptibly() 方法时线程可以响应中断即在等待锁的过程中如果线程被其他线程中断它会立即抛出 InterruptedException 异常而不是一直等待。 下面是一个简单的示例演示了 ReentrantLock 的可中断性 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockInterruptExample {private static final Lock lock new ReentrantLock();public static void main(String[] args) {Thread thread1 new Thread(() - {try {lock.lockInterruptibly(); // 可中断获取锁try {System.out.println(Thread 1 acquired the lock);Thread.sleep(2000); // 模拟持有锁的一些操作} finally {lock.unlock();}} catch (InterruptedException e) {System.out.println(Thread 1 interrupted while waiting for the lock);}});Thread thread2 new Thread(() - {try {lock.lockInterruptibly(); // 可中断获取锁try {System.out.println(Thread 2 acquired the lock);} finally {lock.unlock();}} catch (InterruptedException e) {System.out.println(Thread 2 interrupted while waiting for the lock);}});// 启动第一个线程并让它持有锁thread1.start();// 等待一段时间确保第一个线程先获取到锁try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}// 启动第二个线程但在获取锁之前中断它thread2.start();thread2.interrupt();} }结果输出: Thread 1 acquired the lock Thread 2 interrupted while waiting for the lock第二个线程在获取锁之前被中断, 当中断时抛出InterruptedException, 从而可以在中断的处理代码块中执行相应的逻辑。 2.超时获取 ReentrantLock提供了一种超时获取锁的方式即通过 tryLock(long time, TimeUnit unit) 方法线程在一定的时间范围内尝试获取锁如果在指定的时间内获取到锁则返回 true否则返回 false。这样可以避免线程一直阻塞等待锁而是在一定时间内尝试获取如果获取不到则可以执行其他逻辑或放弃锁的获取。 方法的参数 time 表示等待时间的数量unit 表示等待时间的单位。如果在指定的时间内获取到锁方法返回 true否则返回 false。 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.TimeUnit;public class ReentrantLockTimeoutExample {private static final Lock lock new ReentrantLock();public static void main(String[] args) {Thread thread new Thread(() - {try {if (lock.tryLock(2, TimeUnit.SECONDS)) { // 尝试在2秒内获取锁try {System.out.println(Thread acquired the lock);} finally {lock.unlock();}} else {System.out.println(Thread failed to acquire the lock within 2 seconds);}} catch (InterruptedException e) {System.out.println(Thread interrupted while waiting for the lock);}});// 启动线程thread.start();// 等待一段时间后中断线程try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}thread.interrupt(); // 中断线程} }在上述示例中一个线程尝试在2秒内获取锁如果在2秒内获取到锁则执行相应的逻辑否则放弃锁的获取。在等待的过程中另一个线程对该线程进行中断。在中断的情况下tryLock 方法会抛出 InterruptedException 异常并在异常处理代码块中执行相应的逻辑。这就是 ReentrantLock 的超时获取。 3.条件变量 ReentrantLock 提供了与锁关联的条件变量Condition条件变量允许线程以灵活的方式进行等待和通知以实现更复杂的线程协作。条件变量提供了一种在某些条件不满足时线程等待的机制并在条件满足时通知其他线程的方式。 要使用 ReentrantLock 的条件变量首先需要通过 ReentrantLock 的 newCondition() 方法创建一个条件变量。然后可以使用条件变量的 await() 方法让线程等待条件满足以及使用 signal() 或 signalAll() 方法通知其他等待的线程条件已经满足。 下面是一个简单的示例演示了 ReentrantLock 的条件变量的基本用法 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class ConditionExample {private final Lock lock new ReentrantLock();private final Condition condition lock.newCondition();private boolean isConditionMet false;public void awaitCondition() throws InterruptedException {lock.lock();try {while (!isConditionMet) {// 等待条件满足condition.await();}// 执行条件满足后的操作System.out.println(Condition is met!);} finally {lock.unlock();}}public void signalCondition() {lock.lock();try {// 改变条件isConditionMet true;// 通知等待的线程条件已满足condition.signal();} finally {lock.unlock();}}public static void main(String[] args) {ConditionExample example new ConditionExample();// 启动一个线程等待条件new Thread(() - {try {example.awaitCondition();} catch (InterruptedException e) {e.printStackTrace();}}).start();// 主线程改变条件并通知等待的线程example.signalCondition();} } 在这个例子中awaitCondition 方法用于等待条件满足而 signalCondition 方法用于改变条件并通知等待的线程。在使用条件变量时通常需要在获取锁后使用 await 方法等待条件而在满足条件时使用 signal 或 signalAll 方法通知等待的线程。条件变量的使用有助于实现更灵活的线程协作。 condition.await()会阻塞线程运行吗? 是的condition.await()方法会阻塞当前线程的执行。在 ReentrantLock 中await() 方法用于使当前线程等待并释放当前线程持有的锁直到其他线程调用相应的 signal() 或 signalAll() 方法或者被中断或者超时才会继续执行。 具体来说在 await() 被调用时它会释放当前线程持有的锁使其他线程有机会获取这个锁。当条件满足时通过调用 signal() 或 signalAll() 来唤醒一个或所有等待的线程。被唤醒的线程会尝试重新获得锁然后继续执行。 awaitCondition 方法中的 condition.await() 会使调用该方法的线程等待直到其他线程调用 signalCondition 方法将条件设置为满足并唤醒等待的线程。 需要注意的是在使用 await() 之前必须先获得与 Condition 相关联的锁否则会抛出 IllegalMonitorStateException。在 await() 期间线程会释放锁以便其他线程可以进入相应的临界区。 isConditionMet并没有使用voliate, 在线程中是怎么感知它的值变成true 虽然确实没有使用 volatile 关键字来声明 isConditionMet 变量但是它是在同一个锁的保护下被读取和修改的。 在Java中当一个线程在获取锁的时候会从主内存中读取共享变量的最新值并在执行过程中将其缓存在线程的本地内存中。其他线程在获取同一把锁时会从主内存中重新读取共享变量的值。因为 ReentrantLock 是一个可重入锁同一个线程在获取锁的时候不会真正释放锁因此它的本地内存中的共享变量值是可见的。 在你的例子中awaitCondition 方法中的 while (!isConditionMet) 中的读取操作和 signalCondition 方法中的写入操作都在同一个 ReentrantLock 的保护下这确保了线程在获取锁的时候能够看到最新的共享变量值。 虽然没有使用 volatile但由于所有对 isConditionMet 的读取和写入都在同一把锁的保护下因此在这个特定的上下文中是可以保证可见性的。要注意的是如果 isConditionMet 不是在同一个锁的保护下进行读写或者在其他地方可能会涉及到多线程并发访问那么使用 volatile 或其他同步手段可能是更安全的选择。 1.3 CAS的原理和优缺点 CASCompare And Swap(比较并交换)是一种多线程同步的原子操作, 用于实现多线程环境下的数据共享. CAS操作包含三个参数 内存地址: 需要进行原子操作的内存地址期望值: 预期内存位置的当前值, 可以理解为更新前的值, 用于比较新值 1.原理: 读取内存值: CAS首先读取内存地址的当前值, 这个值通常称为期望值执行操作: CAS执行相应的操作, 例如给期望值赋值, 或者其他复杂的操作, 得到新值比较值: CAS比较期望值与当前内存地址的实际值是否相等, 如果相等, 说明在读取和执行操作的过程中, 没有其他线程修改了这个值更新值: 比较成功后, CAS将新值写回到内存位置, 如果在这个过程中其他线程修改了内存位置的值CAS会失败。检查CAS的结果: CAS操作通常返回一个布尔值指示操作是否成功。如果操作成功表示CAS过程中没有其他线程干扰如果失败则可能需要重新尝试整个CAS过程, 直到CAS操作成功, 或达到某个预定的重试次数 2.缺点: 循环时间长, 开销大: CAS 操作需要通过循环来不断尝试更新变量的值直到成功。在高并发情况下可能需要多次尝试才能成功导致循环时间较长增加了开销。ABA 问题: CAS 操作本质上是比较并交换但它不会关心变量的值在比较前后是否发生了其他变化。这可能导致ABA问题即一个值在经过一系列操作后又变回原始值但 CAS 操作无法察觉到这种变化 1.4 synchronized与Lock的区别难度★★ 频率★★★★ synchronizedLock实现方式Java 内置的关键字是一个接口锁的获取方式使用关键字修饰的同步代码块或方法在进入时会自动获取锁在退出时自动释放锁。如果发生异常锁也会被释放需要手动调用 Lock 接口的 lock() 方法获取锁使用 unlock() 方法释放锁。通常使用 try-finally 语句确保在获取锁后最终会释放锁以处理异常情况。可中断性不支持中断。如果一个线程在获取锁的过程中被中断它会一直等待锁的释放。支持中断。线程可以在等待锁的过程中响应中断从而提高了对中断的响应性公平性不保证公平性。线程争夺锁的顺序是不确定的可能导致某些线程一直无法获取锁。可以选择是否公平。ReentrantLock 的构造方法可以传入一个参数用于指定锁是否为公平锁默认为非公平锁。条件变量内置的 wait() 和 notify() 方法用于支持条件等待和通知。Lock 接口提供了显式的条件变量可以使用 newCondition() 方法创建条件对象并使用 await()、signal() 和 signalAll() 方法进行等待和通知 1.5 常用的原子类有哪些, 它们是如何保证原子性的? 基本类型 AtomicBooleanAtomicIntegerAtomicLong 引用类型 AtomicReferenceAtomicStampedReferenceAtomicReferenceFieldUpdaterAtomicMarkableReference 数组类型 AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray 字段类型 AtomicIntegerFieldUpdaterAtomicLongFieldUpdaterAtomicStampedFieldUpdater JDK8新增原子类简介 DoubleAccumulatorLongAccumulatorDoubleAdderLongAdder 原子类的实现通常使用CAS操作
http://www.yutouwan.com/news/297559/

相关文章:

  • 网站广告怎样做c#做的网站怎么上传图片
  • 什么app做网站餐饮营销方案
  • 网站 备案 多久吾享crm客户管理系统
  • 中山h5网站建设线上免费推广平台都有哪些
  • 青岛企业网站建设优化wordpress设置标题
  • 网站设计与平面设计区别在线建站网站
  • 湛江网站建设策划方案上海网站开发哪家好
  • 临沂市网站建设国内外贸平台
  • 学习做网站教程做网站管理好吗
  • 公司免费网站域名网站接入地查询
  • 响应式网站如何做的莆田seo快速排名
  • 贸易网站源码微信分销系统软件开发
  • 迁安网站开发做网站用什么源码
  • 如何用dw做旅游网站目录wordpress3.9.x
  • 华为云建站视频教程建筑资建设库网站缺陷
  • 网站集约化建设纪要信息流网站建设
  • 用c做网站深圳品牌网站建设公司
  • 做图片类型网站需要什么服务器wordpress 小蘑菇
  • 搜网站的关键词上海公司网页设计
  • 怎么看网站开发语言是哪种福州seo排名收费
  • 用dw做音乐网站从化网站建设方案
  • 一般网站建设需要多少钱做网站一万
  • 网站流量50g织梦网站做seo优化
  • 网站开发语言学习C 吗传奇手游下载
  • 无锡建设局评职称网站电子商务网站建设实训论文
  • 山西省轻工建设有限责网站安阳吧
  • 校园网站建设经费申请报告wordpress 插件交互
  • 重庆建一个网站大概要多少钱南昌做网站和微信小程序的公司
  • 上海网站开发公司排名中国建设银行的网站用户名是什么
  • 郑州网站seo公司网站添加在线支付功能