并发编程
文章平均质量分 86
并发是同学们排成两队,然而却只有一个咖啡机在工作,所以两个队列排在前面的同学交替使用咖啡机;「并行」则是两台咖啡机分别服务两个独立的同学队列,它们同时进行,互不干扰。
这样的例子简单易懂,但依然还需要更进一步说明的是,「并发」与「并行」其实并不是同一个维度上非黑即白的两个对立的概念。
样子的木偶
万般皆下品,惟有读书高
展开
-
CompletableFuture应用&源码分析
平时多线程开发一般就是使用Runnable,Callable,Thread,FutureTask,ThreadPoolExecutor这些内容和并发编程息息相关。相对来对来说成本都不高,多多使用是可以熟悉这些内容。这些内容组合在一起去解决一些并发编程的问题时,很多时候没有办法很方便的去完成异步编程的操作。Thread + Runnable:执行异步任务,但是没有返回结果Thread + Callable + FutureTask:完整一个可以有返回结果的异步任务。原创 2024-01-21 13:49:31 · 1024 阅读 · 0 评论 -
FutureTask应用&源码分析
FutureTask是一个可以取消异步任务的类。FutureTask对Future做的一个基本实现。可以调用方法区开始和取消一个任务。一般是配合Callable去使用。异步任务启动之后,可以获取一个绑定当前异步任务的FutureTask。可以基于FutureTask的方法去取消任务,查看任务是否结果,以及获取任务的返回结果。FutureTask内部的整体结构中,实现了RunnableFuture的接口,这个接口又继承了Runnable, Future这个两个接口。原创 2024-01-21 13:48:26 · 367 阅读 · 0 评论 -
Semaphone应用&源码分析
sync,ReentrantLock是互斥锁,保证一个资源同一时间只允许被一个线程访问Semaphore(信号量)保证1个或多个资源可以被指定数量的线程同时访问底层实现是基于AQS去做的。Semaphore底层也是基于AQS的state属性做一个计数器的维护。state的值就代表当前共享资源的个数。如果一个线程需要获取的1或多个资源,直接查看state的标识的资源个数是否足够,如果足够的,直接对state - 1拿到当前资源。如果资源不够,当前线程就需要挂起等待。原创 2024-01-21 13:47:15 · 840 阅读 · 0 评论 -
CyclicBarrier应用&源码分析
从名字上来看CyclicBarrier,就是代表循环屏障Barrier屏障:让一个或多个线程达到一个屏障点,会被阻塞。屏障点会有一个数值,当达到一个线程阻塞在屏障点时,就会对屏障点的数值进行-1操作,当屏障点数值减为0时,屏障就会打开,唤醒所有阻塞在屏障点的线程。在释放屏障点之后,可以先执行一个任务,再让所有阻塞被唤醒的线程继续之后后续任务。Cyclic循环:所有线程被释放后,屏障点的数值可以再次被重置。CyclicBarrier一般被称为栅栏。原创 2024-01-20 12:34:54 · 813 阅读 · 0 评论 -
CountDownLatch应用&源码分析
CountDownLatch就是JUC包下的一个工具,整个工具最核心的功能就是计数器。如果有三个业务需要并行处理,并且需要知道三个业务全部都处理完毕了。需要一个并发安全的计数器来操作。CountDownLatch就可以实现。给CountDownLatch设置一个数值。可以设置3。每个业务处理完毕之后,执行一次countDown方法,指定的3每次在执行countDown方法时,对3进行-1。主线程可以在业务处理时,执行await,主线程会阻塞等待任务处理完毕。原创 2024-01-20 12:33:25 · 497 阅读 · 0 评论 -
CopyOnWriteArrayList介绍
CopyOnWriteArrayList是一个线程安全的ArrayList。CopyOnWriteArrayList是基于lock锁和数组副本的形式去保证线程安全。在写数据时,需要先获取lock锁,需要复制一个副本数组,将数据插入到副本数组中,将副本数组赋值给CopyOnWriteArrayList中的array。原创 2024-01-19 21:40:58 · 438 阅读 · 0 评论 -
ConcurrentHashMap介绍
红黑树是一种特殊的平衡二叉树,首选具备了平衡二叉树的特点:左子树和右子数的高度差不会超过1,如果超过了,平衡二叉树就会基于左旋和右旋的操作,实现自平衡。每个节点必须是红色或者黑色。根节点必须是黑色。如果当前节点是红色,子节点必须是黑色所有叶子节点都是黑色。从任意节点到每个叶子节点的路径中,黑色节点的数量是相同的。当对红黑树进行增删操作时,可能会破坏平衡或者是特性,这是红黑树就需要基于左旋、右旋、变色来保证平衡和特性。原创 2024-01-19 21:38:30 · 1405 阅读 · 0 评论 -
线程池介绍
首先ThreadPoolExecutor中,一共提供了7个参数,每个参数都是非常核心的属性,在线程池去执行任务时,每个参数都有决定性的作用。但是如果直接采用JDK提供的方式去构建,可以设置的核心参数最多就两个,这样就会导致对线程池的控制粒度很粗。所以在阿里规范中也推荐自己去自定义线程池。手动的去new ThreadPoolExecutor设置他的一些核心属性。自定义构建线程池,可以细粒度的控制线程池,去管理内存的属性,并且针对一些参数的设置可能更好的在后期排查问题。原创 2024-01-17 11:28:02 · 1206 阅读 · 0 评论 -
SynchronousQueue介绍
SynchronousQueue这个阻塞队列和其他的阻塞队列有很大的区别在咱们的概念中,队列肯定是要存储数据的,但是SynchronousQueue不会存储数据的SynchronousQueue队列中,他不存储数据,存储生产者或者是消费者当存储一个生产者到SynchronousQueue队列中之后,生产者会阻塞(看你调用的方法)如果在阻塞期间有消费者来匹配,生产者就会将绑定的消息交给消费者生产者得等阻塞结果,或者不允许阻塞,那么就直接失败生产者在阻塞期间,如果线程中断,直接告辞。原创 2024-01-17 11:24:41 · 918 阅读 · 0 评论 -
DelayQueue
DelayQueue就是一个延迟队列,生产者写入一个消息,这个消息还有直接被消费的延迟时间。需要让消息具有延迟的特性。DelayQueue也是基于二叉堆结构实现的,甚至本事就是基于PriorityQueue实现的功能。二叉堆结构每次获取的是栈顶的数据,需要让DelayQueue中的数据,在比较时,跟根据延迟时间做比较,剩余时间最短的要放在栈顶。查看DelayQueue类信息:基于上述特点,声明一个可以写入DelayQueue的元素类在使用时,查看到DelayQueue底层用了PriorityQueue,原创 2024-01-16 15:00:59 · 390 阅读 · 0 评论 -
LinkedBlockingQueue
查看LinkedBlockingQueue是如何存储数据,并且实现链表结构的。查看LinkedBlockingQueue的有参构造。查看LinkedBlockingQueue的其他属性。从remove方法开始,查看消费者获取数据的方式。你懂得,还是走offer方法。原创 2024-01-15 16:50:24 · 366 阅读 · 0 评论 -
ArrayBlockingQueue
阻塞队列中,如果需要线程挂起操作,判断有无数据的位置采用的是while循环 ,为什么不能换成if。C此时消费一条数据,执行notFull.signal()唤醒一个线程,A线程被唤醒。E走判断,发现有空余位置,可以添加数据到队列,E添加数据,走enqueue。如果判断是if,A在E释放锁资源后,拿到锁资源,直接走enqueue方法。此时A线程就是在putIndex的位置,覆盖掉之前的数据,造成数据安全问题。线程A,线程B,线程E,线程C。如果队列是满的, 就一直挂起,直到被唤醒,或者被中断。原创 2024-01-15 16:43:52 · 477 阅读 · 0 评论 -
java基础类库StringBuffer类
实际上与StringBuffer类还有一个类似的功能类StringBuilder类,这个类是在JDK1.5之后提供的,该类中提供的方法与StringBuffer类相同,区别在于StringBuffer类中的方法属于线程安全的,全都使用了synchronized关键字进行标注,而StringBuilder类属于非线程安全的。也就是说所有的”+“在我们编译后都变为了StringBuffer中的append()方法,并且在程序中String类对象和StringBuffer类对象本来就可以互相转换。......原创 2022-07-26 11:26:39 · 226 阅读 · 2 评论 -
Java多线程编程大完结,从入门到提高,一点一案例(真的不能再有比这更详细了)
因为现在程序执行,没有其他线程去控制flag的内容,所以现在这个时候,我们就可以通过改变flag来控制程序执行,但是万一有其他线程去控制flag的话,一旦其他线程阻塞导致flag的值无法改变,这个时候就会发现线程无法停止了。所以在的线程里面可以进行守护线程的定义,也就是说如果现在主线程或者其他线程还在执行的时候,那么守护线程将一直存在,并且运行在后台状态。在多线程启动使用的是Thread类里面的start()方法,而多线程的停止处理,Thread的stop()方法已经废除,不建议使用。...原创 2022-07-24 11:28:12 · 406 阅读 · 28 评论 -
java多线程编程综合案例
设计一个生产电脑和搬运电脑的类,要求生产一台电脑就搬走一台电脑,如果没有新电脑的生产就等待新电脑生产;如果生产出的电脑没有搬走,则要等待电脑搬走之后再生产,并统计出电脑生产的数量。实现一个竞拍抢答程序要求设置三个抢答者(三个线程),而后发出抢答指令,抢答成功给出抢答成功提示,抢答失败给出抢答失败提示。设计4个线程对象,两个线程执行减操作,两个线程执行加操作。由于需要牵扯到数据的返回所以使用Callable更简单。...原创 2022-07-24 11:20:41 · 615 阅读 · 3 评论 -
Java多线程编程(多线程深入话题)
因为现在程序执行,没有其他线程去控制flag的内容,所以现在这个时候,我们就可以通过改变flag来控制程序执行,但是万一有其他线程去控制flag的话,一旦其他线程阻塞导致flag的值无法改变,这个时候就会发现线程无法停止了。所以在的线程里面可以进行守护线程的定义,也就是说如果现在主线程或者其他线程还在执行的时候,那么守护线程将一直存在,并且运行在后台状态。之所以废除掉这些方法,主要的原因是因为这些方法有的可能导致线程死锁,这个时候我们需要线程停止就需要线程柔和的方式。还要几个方法也被禁用。...原创 2022-07-22 21:08:52 · 185 阅读 · 2 评论 -
java多线程编程(综合案例:生产者与消费者)
人如果要解决问题,首先要解决数据同步问题,如果要想解决数据同步问题最简单的就是使用同步代码块或同步方法,于是在这个时候对于同步的处理就可以直接在Message类中完成。到此,程序执行正常,生产消费一步一步进行,这种处理形式就是在进行多线程开发之中最原始的处理方案,整个等待、同步过程都是通过原生代码实现控制。如果现在想要解决生产者与消费者的问题,那么最好的解决方案就是使用等待唤醒机制,对于等待唤醒机制主要用到object类中的方法。解决完同步问题后,数据信息保持一致,但是不能避免数据重复问题。......原创 2022-07-21 20:11:42 · 553 阅读 · 6 评论 -
Java多线程(线程的同步与锁死)
在多线程处理之中,可以利用Runnable描述多个线程操作的资源,而Thread描述每一个线程对象,于是当多个线程访问同一资源的时候,如果处理不当就会产生数据错误;用sleep()对网络延迟进行模拟,当第一个线程进入后开始休眠,休眠后开始执行ticket–操作,这个时候可能第二个线程也进入,但是第一个线程可能已经进入第三步;当第一个线程ticket–完成时,第二个线程的已经通过判断也就是说它也可以进入第三步,这个时候票数为0,再进行–操作就变为-1了。锁指的就是当某个线程执行操作的时候其他线程外面等待;..原创 2022-07-20 23:05:15 · 307 阅读 · 3 评论 -
Java多线程编程(线程的常用操作)
在之前的线程休眠中发现里面提供有一个中断异常,这实际上证明线程休眠是可以被打断的,这种打断肯定是由其他线程完成的。从理论上讲线程的优先级越高越有可能先执行(越有可能先抢占到资源)在Thread类里面提供有如下的两个处理方法。我们发现在子线程会和主线程抢占资源进行输出,接下来我们看看在利用了线程的强制执行后的运行状态。可以看出当下x>3后main()开始独占资源,当main()执行完成后其他线程才开始执行。在多线程中,可以先将资源让出去让别的线程先执行,线程的礼让可以用Thread中的方法。...原创 2022-07-19 15:57:33 · 769 阅读 · 5 评论 -
Java多线程开发(进程与线程)
Runnable接口无法在完成后获取一个返回值,所以出现Java.util.concurrent.Callable接口可以在线程完成后返回一个值。在方法介绍上,说明又时候我们并不一定都可以正常结束返回结果,这时就需要我们记得抛出异常。Thread类里面的start()方法实现多线程,于是我们就需要去观察Thread的。从上方代码我们可以看出由于没有继承Thread类,但是我们又必须要使用。将依次执行,但是在同一个时间点上只会有一个程序执行(单核),多核可。进程是在操作系统上的划分,线程是在进程上的划分。..原创 2022-07-18 16:46:37 · 369 阅读 · 10 评论