多线程
文章平均质量分 95
duration~
将语言当做协议,聊天当做通信,将说话的内容当做数据。上下层之间进行交互时所遵循的约定叫做“接口”,通信双方同一层之间的交互所遵循的约定叫做“协议”。
展开
-
DelayQueue延迟队列
DelayQueue是 JUC 包(为我们提供的延迟队列,用于实现延时任务比如订单下单 15 分钟未支付直接取消。它是的一种,底层是一个基于实现的一个无界队列,是线程安全的。DelayQueue中存放的元素必须实现Delayed接口,并且需要重写getDelay()方法(计算是否到期)。默认情况下,DelayQueue会按照到期时间升序编排任务。只有当元素过期时(getDelay()方法返回值小于等于 0),才能从队列中取出。原创 2024-07-20 11:05:16 · 951 阅读 · 0 评论 -
ForkJoin框架与工作窃取算法详解
是 Java 并发包中的并行计算框架,旨在有效执行递归任务和大规模并行计算。其核心思想是通过任务拆分(fork)和任务合并(join)来实现高并行度,它体现的是一种分治思想,适用于能够进行任务拆分的 cpu 密集型运算。并利用工作窃取算法来平衡负载。所谓的任务拆分,是将一个大任务拆分为算法上相同的小任务,直至不能拆分可以直接求解。跟递归相关的一些计算,如归并排序、斐波那契数列、都可以用分治思想进行求解。原创 2024-06-27 20:30:33 · 686 阅读 · 0 评论 -
ReentrantLock原理
ReentrantLock是基于其内部类FairSync(公平锁)和NonFairSync(非公平锁)实现的,并且它的实现依赖于Java同步器框架AbstractQueuedSynchronizer(AQS),AQS使用一个整形的volatile变量state来维护同步状态,这个volatile变量是实现ReentrantLock的关键。ReentrantLock 的公平锁和非公平锁都委托了去请求获取。if (!tryAcquire 是一个抽象方法,是公平与非公平的实现原理所在。原创 2024-06-20 11:24:35 · 868 阅读 · 0 评论 -
JAVA-CopyOnWrite并发集合
概括为"写时复制",通俗的讲是写数据的时候弄出一个新的数组,然后讲旧的数据拷贝过去,更新后再将引用指向新数组。这样在添加删除元素时就不会影响旧数组的读取了,确保高并发时读的效率,但是存在延时。下面以和为例对系列的集合进一步讲解。系列集合通过写时复制机制实现线程安全,适用于读操作频繁且写操作较少的场景。虽然写操作的开销较大,但在读操作占多数的应用中,集合可以提供高效且线程安全的性能。在中,移除元素的操作与添加元素类似,通过复制数组并在新数组上进行操作来实现线程安全。原创 2024-06-15 10:09:09 · 1100 阅读 · 1 评论 -
CompletableFuture用法详解
1.概念Fork/Join 是 JDK 1.7 加入的新的线程池实现,它体现的是一种分治思想,适用于能够进行任务拆分的 cpu 密集型运算所谓的任务拆分,是将一个大任务拆分为算法上相同的小任务,直至不能拆分可以直接求解。跟递归相关的一些计算,如归并排序、斐波那契数列、都可以用分治思想进行求解Fork/Join 在分治的基础上加入了多线程,可以把每个任务的分解和合并交给不同的线程来完成,进一步提升了运算效率Fork/Join 默认会创建与 cpu 核心数大小相同的线程池2.使用。原创 2024-04-16 12:18:09 · 448 阅读 · 0 评论 -
Java的Future机制详解
一个java对象可以看成是一段内存,各个字段都得按照一定的顺序放在这段内存里,同时考虑到对齐要求,可能这些字段不是连续放置的,用这个UNSAFE.objectFieldOffset()方法能准确地告诉你某个字段相对于对象的起始内存地址的字节偏移量,因为是相对偏移量,所以它其实跟某个具体对象又没什么太大关系,跟class的定义和虚拟机的内存模型的实现细节更相关。B图表达的是使用Future模式之后,我们主线程在invoke之后可以立即返回,去做其他的事情,回头再来看看刚才提交的invoke有没有结果。原创 2024-04-16 07:56:17 · 1306 阅读 · 0 评论 -
Semaphore快速上手
Semaphore(信号量)是Java并发编程中的一种同步工具,它可以用来控制同时访问某个特定资源的线程数量。Semaphore维护了一个许可集合,线程可以通过获取和释放许可来进行同步。下面是一个简单的Semaphore使用示例,我们创建了一个具有3个许可的信号量,然后启动5个线程同时访问共享资源。通过使用Semaphore,我们可以更好地控制并发线程对共享资源的访问,从而提高程序的性能和稳定性。方法尝试获取一个许可,如果当前没有可用的许可,它将立即返回false,而不是阻塞线程。方法用于释放一个许可。原创 2024-04-15 23:04:12 · 581 阅读 · 0 评论 -
AQS 原理
全称是 AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架,它是构建锁或者其他同步组件的基础框架。原创 2024-04-11 11:05:50 · 875 阅读 · 0 评论 -
synchronized底层原理
Java中的synchronized有偏向锁、轻量级锁、重量级锁三种形式,分别对应了锁只被一个线程持有、不同线程交替持有锁、多线程竞争锁三种情况。描述重量级锁底层使用的Monitor实现,里面涉及到了用户态和内核态的切换、进程的上下文切换,成本较高,性能比较低。轻量级锁线程加锁的时间是错开的(也就是没有竞争),可以使用轻量级锁来优化。轻量级修改了对象头的锁标志,相对重量级锁性能提升很多。每次修改都是CAS操作,保证原子性偏向锁。原创 2024-04-10 15:39:46 · 986 阅读 · 6 评论 -
CountDownLatch 详解
CountDownLatch 类主要提供了以下方法:构造函数,创建一个 CountDownLatch 对象,并设置初始的计数器值为 count。阻塞当前线程,直到计数器值变为0。如果计数器已经为0,立即返回。如果在等待过程中被中断,则抛出 InterruptedException 异常。阻塞当前线程,直到计数器值变为0或者超时。如果在指定时间内计数器变为0,则返回 true ,否则返回 false。如果在等待过程中被中断,则抛出 InterruptedException 异常。原创 2024-04-05 23:24:36 · 1071 阅读 · 0 评论 -
ThreadPoolExecutor 方法详解
在上一篇文章中,对线程池的创建,各种参数进行了详细的分析,接下来对其他的常用方法和异常处理展开介绍。1.方法 shutdown() 和 shutdownNow()public void shutdown() 方法的作用是使当前未执行完的任务继续执行,而队列中未执行的任务会继续执行,不删除队列中的任务,不再允许添加新的任务,同时 shutdown 方法不会阻塞。原创 2023-12-12 17:51:37 · 1035 阅读 · 2 评论 -
ThreadPoolExecutor 线程池
在开发服务器端软件项目时,软件经常需要处理执行时间很短而数目巨大的请求,如果为每一个请求创建一个新的线程,则会导致性能上的瓶颈。因为JVM 需要频繁地处理线程对象的创建和销毁,如果请求的执行时间很短,则有可能花在创建和销毁线程对象上的时间大于真正执行任务的时间,所以系统性能会大幅降低。JDK 5及以上版本提供了对线程池的支持,主要用于支持高并发的访问处理,并且复用线程对象。原创 2023-12-11 16:56:10 · 1439 阅读 · 0 评论 -
并发集合框架
并发集合框架是为了在多线程环境下提供高效和线程安全的数据结构而设计的。Java 的并发集合框架提供了一组线程安全的集合类,可以在多线程应用程序中使用,以解决并发访问集合时可能出现的竞态条件和线程安全问题。原创 2023-12-06 07:15:00 · 1147 阅读 · 0 评论 -
线程中出现异常的处理
在紧密交织的多线程环境中,异常处理是一个经常被讨论的容易被忽视的关键部分。这并不奇怪,因为在编写并发代码时,管理和理解可能出现的各种异常条件可能是一个挑战。在单线程环境中,发生异常时,异常信息会立刻被捕获并处理,然而,在多线程环境中的异常处理复杂性要高很多。未被正确处理的异常可能导致全局性影响,甚至系统崩溃。这给程序稳定性带来威胁,且可能会导致无法预料的行为。因此,对于编写健壮且可靠的并发代码来说,理解并且正确处理线程中的异常是至关重要的。本文旨在深入探讨Java中线程级别的异常处理。原创 2023-12-04 07:30:00 · 1688 阅读 · 0 评论 -
SimpleDataFormat 非线程安全
SimpleDateFormat类是 Java 中处理日期和时间格式化和解析的类,但它并不是线程安全的。这意味着多个线程不能安全地共享一个SimpleDateFormat实例进行日期和时间的解析和格式化。当多个线程共享同一个SimpleDateFormat实例时,会因为SimpleDateFormat内部维护的日历字段(例如:Calendar对象)等的竞争条件而导致解析和格式化错误。原创 2023-12-03 07:30:00 · 620 阅读 · 0 评论 -
线程组 Thread Group
线程组是 Java 中的一个概念,用于管理线程集合。一个线程组可以包含线程,并且可以是另一个线程组的子项。线程组形成的是一个树状结构,除了系统线程组(根线程组)之外,每个线程组都有一个父线程组。线程可以访问一些有关自己所属线程组的信息,比如线程组的名称,以及线程组中活动线程的数目等。原创 2023-11-30 08:00:00 · 1918 阅读 · 0 评论 -
线程的状态
线程在不同的时期存在不同的状态,状态信息存在中。状态类信息。状态解释。调用与线程有关的方法是造成线程状态改变的主要原因,因果关系如图所示。从图中可知,在调用与线程有关的方法后,线程会进入不同的状态。这些状态之间有些是双向切换,比如 WAITING 和 RUNNING 状态之间可以循环地进行切换,而有些是单向切换,比如线程销毁 ( TERMINATED 状态)后不能自动进入 RUNNING 状态。下面对 6 种线程状态用程序代码的方式进行验证。原创 2023-11-28 08:00:00 · 779 阅读 · 1 评论 -
单例模式与多线程
在单例模式与多线程技术相结合的过程中,我们能发现许多以前从未考虑过的问题。这些不良的程序设计如果应用在商业项目中将会带来非常大的麻烦。线程与某些技术相结合时,我们需要考虑的事情会更多。总的来说,在本节我们只需要考虑一件事,那就是:如何使单例模式与多线程结合时是安全的、正确的。原创 2023-11-25 20:25:06 · 1742 阅读 · 0 评论 -
定时器的使用
定时/计划功能在移动开发领域使用较多,比如Android技术,定时功能在Java种主要通过Timer类实现,因为它在内部还是使用多线程的方式进行处理,所以和线程技术还是有非常大的关联。原创 2023-11-22 10:59:27 · 626 阅读 · 0 评论 -
ReentrantReadWriteLock 的使用
ReentrantLock 类具有完全互斥排它的特点,同一时间只有一个线程在执行ReentrantLock.lock() 方法后面的任务,这样做虽然保证了同时写实例变量的线程安全行,但效率是非常低下的。在 JDK 中提供了一种读写锁 ReentrantReadWriteLock 类,可以在同时进行读操作时不需要同步执行,提升运行效率,加快运行效率。这两个类之间没有继承关系。读写锁表示有两个锁,一个是读操作相关的锁,也叫共享锁,另一个是写操作相关的锁,也叫排它锁。原创 2023-11-15 22:34:57 · 96 阅读 · 1 评论 -
ReentrantLock的使用(补充)
本文是基于ReentrantLock类使用--同步机制分析这篇文章进行对 ReentrantLock 锁常见的其他方法的补充。原创 2023-11-15 08:00:00 · 242 阅读 · 0 评论 -
ReentrantLock类使用--同步机制分析
在Java多线程中可以使用 synchronized 关键字来实现线程间同步 ,不过在 JDK1.5 中新增的ReentranLock 类也能达到同样的效果,并且在扩展功能上更加强大,比如具有嗅探锁定、多路分支通知等功能。原创 2023-11-10 22:56:53 · 260 阅读 · 2 评论 -
InheritableThreadLocal详解
使用类InheritableThreadLocal 可以再子线程中取得父线程继承下来的值,而ThreadLocal并不具备,所以让我们继续了解。原创 2023-11-09 21:00:48 · 742 阅读 · 1 评论 -
ThreadLocal详解
变量值的共享可以使用 public static 变量的形式,所有的线程都使用同一个 public static 变量,那如果想实现每一个线程都有自己的变量该如何解决呢?JDK提供的ThreadLocal就可以派上用场了。类ThreadLocal主要的作用就是将当数据放入当前线程对象的Map里,这个Map是Thread类的实例变量。原创 2023-11-08 20:50:42 · 378 阅读 · 5 评论 -
join() 在多线程中的使用
在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束,这时如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据中的值,这个时候就要用到 join() 方法了。方法 join() 的作用是等待线程对象销毁。原创 2023-11-07 20:04:33 · 2816 阅读 · 0 评论 -
生产者/消费者模式
在代码中确实已经通过 wait / notify 进行通信了,但不保证 notify 唤醒的是异类,也许是同类,比如 ”生产者“ 唤醒 ”生产者“ ,或 ”消费者“ 唤醒 ”消费者“ 这样的情况,如果这种情况越来越多,就会导致所有的线程都不能继续运行下去,大家都在等待,程序最后也就呈”假死“状态了。但如果在此实验的基础上设计出多个生产者和多个消费者,那么在运行的过程中极有可能出现连续生产值,导致值被覆盖,以及连续消费值,导致消费的值都是空值的情况。创建新的实验代码,将原来的代码全部复制过去。原创 2023-10-12 22:45:45 · 127 阅读 · 1 评论 -
wait/notify机制
wait/notify(等待/通知)机制在生活中比比皆是,比如在就餐时就会出现,如图:厨师和服务员要在"菜品传递台"上交互,在这期间会想到几个问题:1)厨师做完一个菜的时间未知,所以厨师将菜品放到"菜品传递台" 上的时间也未知。2)服务员取到菜的时间取决于厨师,所以服务员就有"wait"状态。3)服务员如何能取到菜呢?这又得取决于厨师。厨师将菜放在“菜品传递台”上,其实就是相当于一种notify,这时服务员才可以拿到菜并交给就餐者。4)在这个过程中出现了“wait/notify机制”。原创 2023-10-09 20:04:51 · 326 阅读 · 2 评论 -
Volatile 关键字
在Java中 volatile 关键字就像一个神话一样,几乎在各种博客,微信订阅号,聊天群被反复谈起,可见程序员对此是又爱又恨,也说明volatile在多线程领域的重要性。volatile 在使用上有 以下 3个特性。1)可见性: B线程能马上看到A线程更改的数据。2)原子性: 原子性是指一组操作在执行时 不能被打断。如果在中间执行其他操作会导致者一组操作不连续,获得错误的结果,即非原子性。 volatile的原子性体现在赋值原子性,在 32 位 JDK中对 64 位数据类型执行赋值操作时会写两次,原创 2023-10-02 20:26:53 · 235 阅读 · 3 评论 -
对象及变量的并发访问(下)
synchronized 关键字还可以应用在静态方法上,如果这样写,那是对当前的*.java文件对应的Class类的对象进行持锁,Class类的对象是单例的,更具体的说,在静态方法上使用synchronized关键字声明同步方法时,是使用当前静态方法所在类对应Class类的单例对象作为锁的。原创 2023-10-01 14:09:06 · 153 阅读 · 0 评论 -
对象及变量的并发访问控制(上)
综上所述,两个线程同时访问一个对象中的同步方法时一定是线程安全的,本次实验,由于线程是同步访问,并且a先执行,所以先输出a,然后输出b,但是完全有可能出现b线程先运行,那么就会先输出b后输出a。锁非 this对象有一定的优点,就是如果一个类中如果有很多synchronized方法,这时虽然能实现同步,但影响运行效率,如果使用同步代码块锁非this对象,则synchronized(非this)代码块中的程序与同步方法是异步的,因为是两把锁,不与其他锁this同步方法争抢this锁,可大大提高运行效率。原创 2023-09-30 05:45:00 · 175 阅读 · 0 评论 -
Java多线程技能
1).线程可以理解为在进程中独立运行的子任务。2).进程负责向操作系统申请资源。在一个进程中,多个线程可以共享进程中相同的内存或文件资源。先有进程,后有线程。在一个进程中可以创建多个线程3).进程虽然是相互独立的,但是他们可以共享通信,较为通用的方式是使用HTTP协议和Socket。4).进程拥有共享的系统资源,比如内存,网络端口,供其内部线程使用。5).进程较重,因为创建进程需要操作系统分配资源,会占用内存。6).线程存在与进程中,是进程的一个子集,先有进程,后有线程。原创 2023-09-21 21:02:51 · 149 阅读 · 5 评论