
Java 并发编程
文章平均质量分 67
介绍 Java 并发编程知识
半夏_2021
系统恒久远,代码永流传!
展开
-
Hook线程以及捕获线程执行异常
文章目录获取线程运行时异常注入钩子线程Hook线程实战Hook线程使用应用场景获取线程运行时异常在Thread类中,关于处理运行时异常API总共有四个setUncaughtExceptionHandler(UncaughtExceptionHandler eh) :为某个特定线程指定UncaughtExceptionHandlersetDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) : 设置全局的UncaughtExce原创 2021-08-31 16:47:13 · 438 阅读 · 0 评论 -
史上最全最详细的ThreadLocal 使用
文章目录ThreadLocal 简介ThreadLocal 的四个方法ThreadLocal 简介一种解决多线程环境下成员变量的问题的方案,但是与线程同步无关,其思路是为每一个线程创建一个单独的变量副本,从而每个线程都可以独立地改变所拥有的变量副本,而不会影响其他线程所对应的副本。ThreadLocal不是用于解决共享变量的问题的,也不是为了协调线程同步而存在,而是为了方便每个线程处理自己的状态而引入的一个机制。ThreadLocal 的四个方法void set(Object value)原创 2021-08-31 15:48:47 · 12797 阅读 · 1 评论 -
Java FutureTask 详解
Future模式的实现方式Data 数据接口 public interface Data { String getRequest(); }FutureClient:对外统一类public class FutureClient { public Data request(final String queryStr){ //1.我想要一个代理对象( Data接口的实现类 )先返回给发送请求的客户单,告诉他请求已经接收到,可以做其他的事情原创 2021-08-29 16:34:55 · 937 阅读 · 0 评论 -
Java8 CompletionService 使用
CompletionService实际上可以看做是Executor和BlockingQueue的结合体。CompletionService在接收到要执行的任务时,通过类似BlockingQueue的 put 和 take 获得任务执行的结果。CompletionService的一个实现是ExecutorCompletionService,ExecutorCompletionService把具体的计算任务交给Executor完成。在实现上,ExecutorCompletionService在构造函数中会创原创 2021-08-29 16:15:56 · 267 阅读 · 0 评论 -
使用线程池的注意事项
原创 2021-08-29 15:57:40 · 246 阅读 · 0 评论 -
怎样对Java 线程池进行监控?
监控的属性taskCount : 线程池需要执行的任务数量completedTaskCount: 线程池在运行过程中已完成的任务数量largestPoolSize : 线程池里曾经创建过的最大线程数量getPoolSize : 线程池的线程数量getActiveCount : 获取活动的线程数监控示例监控方法public long getTaskCount() //线程池已执行与未执行的任务总数public long getCompletedTaskCount() //已完成的任务数原创 2021-08-27 12:43:25 · 1654 阅读 · 0 评论 -
java ThreadPoolExecutor 详解
构造方法如下:public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)corePoolSize核心线程数,当提交一个任务的时候,线程池创建一个新的线程执行任务,直到原创 2021-08-27 11:27:48 · 1707 阅读 · 0 评论 -
为什么线程池不允许Executors去创建,而是通过ThreadPoolExecutor的方式?
我们先看一下 Executors 预定义的线程池:newFixedThreadPool创建使用固定线程数的FixedThreadPool的API。适用于为了满足资源管理的需求,而需要限制当前线程数量的应用场景,它适用于负载比较重的服务器。FixedThreadPool的corePoolSize和maximumPoolSize都被设置为创建FixedThreadPool时指定的参数nThreads。当线程池中的线程数大于corePoolSize时,keepAliveTime为多余的空闲线程等待新任务的。原创 2021-08-25 10:21:03 · 252 阅读 · 0 评论 -
Java并发工具之Semaphore
信号量的意思,它的作用是控制访问特定资源的线程数目,底层依赖AQS 的状态state,是在生产当中比较常用的一个工具类。怎么使用:构造方法public Semaphore(int permits)// permits 表示许可线程的数量// fair 表示公平性,如果这个设为 true 的话,下次执行的线程会是等待最久的线程public Semaphore(int permits, boolean fair)重要方法public void acquire() throws Int原创 2021-08-14 10:29:30 · 147 阅读 · 0 评论 -
Java并发工具之CyclicBarrier
它允许一组线程互相等待,直到到达某个公共屏障等你。通俗讲: 让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。底层采用ReentrantLock + Condition 实现API:cyclicBarrier.await();应用场景:多线程结果的合并的操作,用于多线程计算数据,最后合并计算结果的应用场景可以用于多线程计算数据,最后合并计算结果的场景。例如,用一个Excel保存了用户所有银行流水,每个Sheet保存一个账户近一年的原创 2021-08-14 10:21:29 · 120 阅读 · 0 评论 -
Java并发工具类之CountDownLatch
CountDownLatch简介在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数初始化CountDownLatch,由于调用了countDown()方法,所以在当前计数到达零之前,await()方法会一直受阻塞,之后,会释放所有等待的 线程 ,await的所有后续调用都将立即返回。和CyclicBarrier的区别?CountDownLatch 的作用是允许1或者N个线程等待其他线程 完成执行;而CyclicBarrier则是允许N个线程相互等待。Coun原创 2021-08-13 16:20:51 · 255 阅读 · 0 评论 -
Java DelayQueue的使用及应用场景
DelayQueue 简介由优先级堆支持的、基于时间的调度队列,内部基于无界队列PriorityQueue实现,而无界队列基于数组的扩容实现。队列创建BlockingQueue<String> blockingQueue = new DelayQueue();要求入队的对象必须要实现Delayed接口,而Delayed集成自Comparable接口应用场景对缓存超时的数据进行移除当向缓存中添加key-value对时,如果这个key在缓存中存在并且还没有过期,需要用这个key对应原创 2021-08-13 16:06:37 · 933 阅读 · 0 评论 -
Java阻塞队列之ArrayBlockingQueue
ArrayBlockingQueue:基于数组结构的有界阻塞队列(长度不可变);实现: ReentrantLock + Condition应用场景:在线程池中有比较多的应用,生产者消费者场景工作原理: 基于ReentrantLock保证线程安全,根据Condition实现队列满时的阻塞源码分析主要属性// 使用数组存储元素final Object[] items;// 取元素的指针int takeIndex;// 放元素的指针int putIndex;// 元素数量int count;原创 2021-08-13 15:15:17 · 277 阅读 · 0 评论 -
什么是阻塞队列?常见的阻塞队列有哪些?
BlockingQueue,是 java.util.concurrent 包提供的用于解决并发生产者 - 消费者问题的最有用的类,它的特性是在任意时刻只有一个线程可以进行take或者 put操作,并且BlockingQueue提供了超时return null的机制,在许多生产场景里都可以看到这个工具的身影。队列类型无限队列 (unbounded queue ) - 几乎可以无限增长。有限队列 ( bounded queue ) - 定义了最大容量。队列的数据结构通常用链表或者数组实现一般而原创 2021-08-13 15:05:45 · 551 阅读 · 0 评论 -
Java并发之ReentrantLock详解
ReentrantLock的使用使用ReentrantLock进行同步ReentrantLock lock = new ReentrantLock(false);//false为非公平锁,true为公平锁lock.lock() //加锁// 处理逻辑lock.unlock() //解锁ReentrantLock是一种基于AQS框架的应用实现,是JDK中的一种线程并发访问的同步手段,它的功能类似于synchronized是一种互斥锁,可以保证线程安全。而且它具有比synchronized更多的特原创 2021-08-13 10:38:51 · 420 阅读 · 0 评论 -
Java并发之synchronized锁
synchronized 内置锁是一种对象锁(锁的是对象而非引用),作用粒度是对象,可以用来实现对临界资源的同步互斥访问,是可重入的。锁对象普通方法,锁的是当前实例对象静态同步方法,锁的 是当前类的class对象同步方法块,锁的是括号里的 对象原理synchronized是基于JVM内置锁实现,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统的Mutex lock(互斥锁)实现,它是一个重量级锁性能较低。当然,J原创 2021-08-11 11:57:12 · 263 阅读 · 0 评论 -
Java并发之锁的分类
重入锁支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁实现重进入需要解决的2个问题1.线程再次获取锁final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSe原创 2021-08-11 11:43:43 · 252 阅读 · 0 评论 -
Java并发之 volatile详解
volatile关键字的作用保证被volatile修饰的共享 变量对所有线程总是可见的,也就是当一个线程修改了一个被volatile修饰共享变量的值,新值总是可以被其他线程立即得知。禁止指令重排序volatile可见性volatile的可见性作用,我们必须意思到被volatile修饰的变量对所有线程总是可见的,对volatile变量的所有写操作总是能立刻反应到其他线程的public class VolatileVisibilitySample { volatile boolean in原创 2021-08-11 09:49:31 · 419 阅读 · 0 评论 -
Java 内存模型(JMM)
文章目录什么是JMM模型JMM和JVM的区别主内存和工作内存Java内存模型与硬件内存架构的关系JMM存在的必要性什么是JMM模型Java内存模型(Java Memory Model简称JMM)是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。JVM运行程序的实体是线程,而每个线程创建时,JVM都会为其创建一个工作内存(有些地方称为栈空间),用于存储线程私有的数据。Java内存模型中规定所有变量都存储在原创 2021-08-11 08:24:16 · 3574 阅读 · 0 评论 -
Java中的Unsafe
Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。Unsafe类为一原创 2021-08-11 07:58:43 · 462 阅读 · 0 评论 -
AQS使用的设计模式 -模板方法模式
AQS 采用了标准的模版方法设计模式,对外提供的是以下的方法: // 独占模式 public final void acquire(int arg); public final boolean release(int arg); // 独占可中断 public final void acquireInterruptibly(int arg) throws InterruptedException; // 独占带超时时间的 public原创 2021-08-10 16:47:13 · 1915 阅读 · 0 评论 -
设计一个同步工具:该工具在同一时刻,只允许至多3个线程同时访问,超过3个线程的访问将被阻塞。
首先,确定访问模式。TrinityLock能够在同一时刻支持多个线程的访问,这显然是共享式访问,因此,需要使用同步器提供的acquireShared(int args)方法等和Shared相关的方法,这就要求TwinsLock必须重写tryAcquireShared(int args)方法和tryReleaseShared(int args)方法,这样才能保证同步器的共享式同步状态的获取与释放方法得以执行。其次,定义资源数。TrinityLock在同一时刻允许至多三个线程的同时访问,表明同步资源数为3,这原创 2021-08-10 16:42:19 · 576 阅读 · 0 评论 -
怎样使用AQS实现一个独占锁?
/** *类说明:实现我们自己独占锁,可重入 */public class ReenterSelfLock implements Lock { // 静态内部类,自定义同步器 private static class Sync extends AbstractQueuedSynchronizer { // 是否处于占用状态 protected boolean isHeldExclusively() { return getSta原创 2021-08-10 16:39:58 · 155 阅读 · 0 评论 -
Java并发之AQS详解
AQS,全名AbstractQueuedSynchronizer,是一个抽象类的队列式同步器,它的内部通过维护一个状态 volatile int state(共享资源),一个FIFO线程等待队列来实现同步功能。内部通过一个int 类型的成员变量state来控制同步状态:state=0: 说明没有任何线程占有共享资源的锁。state = 1: 说明有线程正在使用共享变量,其他线程必须加入同步队列进行等待。AQS内部通过内部类Node构成FIFO的同步队列来 完成线程获取锁的排队工作,同时原创 2021-08-10 16:15:08 · 501 阅读 · 0 评论 -
什么是CAS?CAS有什么缺点?
文章目录什么是CAS什么是CASCAS 的全称是 Compare And Swap 即比较交换,其算法核心思想如下函数:CAS(V,E,N) 参数:V 表示要更新的变量 E 预期值 N 新值如果 V 值等于 E 值,则将 V 的值设为 N。若 V 值和 E 值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。通俗的理解就是 CAS 操作需要我们提供一个期望值,当期望值与当前线程的变量值相同时,说明还没线程修改该值,当前线程可以进行修改,也就是执行 CAS 操作,但如果期望值与当前线程不符,则说明原创 2021-08-10 15:11:44 · 2263 阅读 · 1 评论 -
什么是上下文切换?如何减少上下文切换?
文章目录导致原因开销如何减少上下文切换即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的执行时间,因为事件片非常短,所有CPU通过不停地切换线程执行,让我们感觉多个线程是同时执行,时间片一般 几十毫秒 (ms)。CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切回这个任务时,可以再加载这个任务的状态。所以任务 从保存到再加载的过程就是一次上下文切换。这原创 2021-08-10 15:00:42 · 462 阅读 · 0 评论 -
守护线程和非守护线程的区别?
守护线程实现方式Thread t = new Thread();t.setDaemon();t.start区别用户线程会阻止java虚拟机的正常停止,即一个java虚拟机只有在其所有用户线程都运行结束的情况下才能正常停止守护线程不会影响java虚拟机的 正常停止,即应用程序中有守护线程在运行也不影响 java虚拟机的正常停止。守护线程通常用于执行一些重要性不很高的任务,例如用户监视其他线程的运行情况如果java虚拟机是被强制停止的,比如在linux系统下使用kill命令强制终止一个jav原创 2021-08-10 14:50:12 · 847 阅读 · 0 评论 -
java线程之间是怎么协作的?
线程之间相互配合,完成某项工作,比如:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程。前者是生产者,后者就是消费者,这种模式隔离了“做什么”(what)和“怎么做”(How),简单的办法是让消费者线程不断地循环检查变量是否符合预期在while循环中设置不满足的条件,如果条件满足则退出while循环,从而完成消费者的工作。却存在如下问题:1) 难以确保及时性。2)难以降低开销。如果降低睡眠的时间,比如休眠1毫秒,这样消费者能更加迅速地原创 2021-08-10 12:01:43 · 181 阅读 · 0 评论 -
在父线程中设置的ThreadLocal变量,怎样在子线程中获取?
首先我们看一个例子public class TestThreadLocal { public static ThreadLocal<String> threadLocal = new ThreadLocal<>(); public static void main( String[] args ) { // 色后置线程变量 threadLocal.set("hello world"); Thread thread原创 2021-08-10 11:32:10 · 3006 阅读 · 1 评论 -
线程的生命周期
线程的生命周期一共有6中,如下:NEW :初始状态,线程被构建,但是还没有调用 start 方法创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动), 也就是说新生状态的线程有自己的内存空间,但该线程并没有运行,此时线程还不是活着的(not alive) 。例如:Thread t1= new Thread();RUNNABLE: 运行状态,JAVA 线程把操作系统中的就绪和运行两种状态统一称为“运行中”,线程已经被启动,正在等待分配CPU时间片。也就通过调用线程实例的s.原创 2021-08-04 18:06:50 · 220 阅读 · 0 评论 -
Java创建线程的四种方式
文章目录继承Thread实现Runnable接口使用ExecutorService实现Callable接口Future实现带返回结果的多线程继承Thread实现Runnable接口使用ExecutorService实现Callable接口Future实现带返回结果的多线程原创 2021-08-04 17:56:20 · 174 阅读 · 0 评论 -
java线程与系统内核线程关系
线程的实现可以分为两类1、用户级线程(User-Level Thread)指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。另外,用户线程是由应用进程利用线程库创建和管理,不依赖于操作系统核心。不需要用户态/核心态切换,速度快。操作系统内核不知道多线程的存在,因此一个线程阻塞将使得整个进程(包括它的所有线程)阻塞。由于这里的处理器时间片分配是以进程为基本单位,所以每个线程执行的时间相对减少。2、内核线线程(Kerne原创 2021-08-04 09:51:39 · 742 阅读 · 0 评论 -
进程与线程的一个简单解释
什么是进程?现代操作系统在运行一个程序时,会为其创建一个进程;例如,启动一个Java程序,操作系统就会创建一个Java进程。进程是OS(操作系统)资源分配的最小单位。进程是程序 运行资源(CPU、内存空间、磁盘IO等)分配的最小单位进程是操作系统进行资源分配的最小单位,其中资源包括:CPU、内存空间、磁盘IO等,同一进程中的多条线程共享该进程中的全部系统资源,而进程和进程之间是相互独立的。进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。进程是原创 2021-08-04 09:37:32 · 219 阅读 · 0 评论 -
CPU核心数和线程数的关系
多核心:也指单芯片多处理器( Chip Multiprocessors,简称CMP),CMP是由美国斯坦福大学提出的,其思想是将大规模并行处理器中的SMP(对称多处理器)集成到同一芯片内,各个处理器并行执行不同的进程。这种依靠多个CPU同时并行地运行程序是实现超高速计算的一个重要方向,称为并行处理。多线程: Simultaneous Multithreading.简称SMT.让同一个处理器上的多个线程同步执行并共享处理器的执行资源。核心数、线程数: 目前主流CPU都是多核的。增加核心数目就是为了增加线原创 2021-08-04 09:31:31 · 3170 阅读 · 0 评论