多线程
文章平均质量分 60
Mr_haining
在逆境中寻求希望!在悲观中寻求快乐!
展开
-
Java并发关键字-synchronized
synchronized简介在学习知识前,我们先来看一个现象:开启了10个线程,每个线程都累加了1000000次,如果结果正确的话自然而然总数就应该是10 * 1000000 = 10000000。可就运行多次结果都不是这个数,而且每次运行结果都不一样。这是为什么了?有什么解决方案了?这就是我们今天要聊的事情。我们已经了解了Java内存模型的一些知识,并且已经知道出现线程安全的主要来源于JMM的设计,主要集中在主内存和线程的工作内存而导致的内存可见性问题,以及重排序导致的问题,进一步知道了hap原创 2021-11-22 11:34:24 · 159 阅读 · 0 评论 -
as-if-serial规则和happens-before规则的区别
为了在不改变程序执行结果的前提下,尽可能地提高程序执行的并行度,我们需要了解as-if-serial规则和happens-before规则文章目录as-if-serial规则happens-before规则happens-before定义具体规则as-if-serial与happens-before的区别as-if-serial规则as-if-serial语义的意思指:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。编译器,runtime 和处理器都必须原创 2021-11-22 10:35:04 · 430 阅读 · 0 评论 -
Exchanger 线程之间交换数据的封装工具类
Java 的 Exchanger 简单说说其特点及应用场景Exchanger 是 JDK 1.5 开始提供的一个用于两个工作线程之间交换数据的封装工具类,简单说就是一个线程在完成一定的事务后想与另一个线程交换数据,则第一个先拿出数据的线程会一直等待第二个线程,直到第二个线程拿着数据到来时才能彼此交换对应数据。其定义为 Exchanger<V> 泛型类型,其中 V 表示可交换的数据类型,对外提供的接口很简单,具体如下: Exchanger():无参构造方法。 V exchang原创 2021-04-08 14:01:34 · 136 阅读 · 0 评论 -
Semaphore使用及原理
1、Semaphore 是什么Semaphore 通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。可以把它简单的理解成我们停车场入口立着的那个显示屏,每有一辆车进入停车场显示屏就会显示剩余车位减1,每有一辆车从停车场出去,显示屏上显示的剩余车辆就会加1,当显示屏上的剩余车位为0时,停车场入口的栏杆就不会再打开,车辆就无法进入停车场了,直到有一辆车从停车场出去为止。2、使用场景朱勇用于那些资源有明确访问数量限制的场景,常用于限流 。.原创 2021-04-07 17:47:02 · 303 阅读 · 0 评论 -
ReentrantReadWriteLock
概述 ReentrantReadWriteLock是Lock的另一种实现方式,我们已经知道了ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个读线程同时访问,但不允许写线程和读线程、写线程和写线程同时访问。相对于排他锁,提高了并发性。在实际应用中,大部分情况下对共享数据(如缓存)的访问都是读操作远多于写操作,这时ReentrantReadWriteLock能够提供比排他锁更好的并发性和吞吐量。 读写锁内部维护了两个锁,一个用原创 2021-04-07 17:14:06 · 179 阅读 · 0 评论 -
Java并发之Condition
在使用Lock之前,我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了。配合Object的wait()、notify()系列方法可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,但是这两者在使用方式以及功能特性上还是有差别的。Object和Condition接口的一些对比。摘自《Java并发编程的艺术》一、Condition接口介绍和示例 首先我们需要明白condition对象是依赖于...原创 2021-04-07 16:39:05 · 130 阅读 · 0 评论 -
Phaser应用场景及实例
适用场景:CountDownLatch和CyclicBarrier都是JDK 1.5引入的,而Phaser是JDK 1.7引入的。Phaser的功能与CountDownLatch和CyclicBarrier有部分重叠,同时也提供了更丰富的语义和更灵活的用法。Phaser顾名思义,与阶段相关。Phaser比较适合这样一种场景,一种任务可以分为多个阶段,现希望多个线程去处理该批任务,对于每个阶段,多个线程可以并发进行,但是希望保证只有前面一个阶段的任务完成之后才能开始后面的任务。这种场景可以使用多个Cy原创 2021-04-07 15:58:58 · 390 阅读 · 0 评论 -
CountDownLatch和CyclicBarrier区别
CyclicBarrier和CountDownLatch 都位于java.util.concurrent 这个包下CountDownLatch CyclicBarrier减计数方式 加计数方式计算为0时释放所有等待的线程 计数达到指定值时释放所有等待线程计数为0时,无法重置 计数达到指定值时,计数置为0重新开始调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 调用await()方法计数加1,若加1后的值不等于构造方法的值,则...原创 2021-04-07 15:42:06 · 140 阅读 · 0 评论 -
CountDownLatch使用
1.CountDownLatch工作原理CountDownLatch在多线程并发编程中充当一个计时器的功能,并且维护一个count的变量,并且其操作都是原子操作,该类主要通过countDown()和await()两个方法实现功能的,首先通过建立CountDownLatch对象,并且传入参数即为count初始值。如果一个线程调用了await()方法,那么这个线程便进入阻塞状态,并进入阻塞队列。如果一个线程调用了countDown()方法,则会使count-1;当count的值为0时,这时候...原创 2021-04-07 15:02:37 · 178 阅读 · 0 评论 -
线程池
线程池ThreadPool:一个是线程的集合,一个是任务的集合指向一个任务队列。线程池装的是一个个线程执行里边一个个的任务,这个任务放在任务队列里边。(1)定义ThreadPoolExecutor有7个参数。分别为:核心线程数、最大线程数、生存时间、时间单位、任务队列、线程工厂(产生线程,线程的名称)、拒绝策略ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS,原创 2021-03-18 23:29:17 · 134 阅读 · 0 评论 -
ThreadLocal
ThreadLocalthreadlocal使用方法很简单static final ThreadLocal<T> sThreadLocal = new ThreadLocal<T>();sThreadLocal.set()sThreadLocal.get()threadlocal而是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据,官方解释如下。/** * This class provides thr..原创 2021-03-07 16:12:28 · 135 阅读 · 0 评论 -
AQS
AQS的核心:用CAS的操作替代了锁整条链表的操作,这也是为什么它效率高的原因之一。jdk1.8之后增加了VarHandle(1)普通属性也可以进行原子操作。(2)比反射快,直接操纵二进制码。原创 2021-03-02 23:53:46 · 105 阅读 · 0 评论 -
wait和notify
面试题:实现一个容器,提供两个方法,add,size写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束方案:(1)使用wait和notify理由:如果给lists添加volatile之后,t2能够接到通知,但是,t2线程的死循环很浪费cpu,如果不用死循环,该怎么做呢?这里使用wait和notify,wait会释放锁,而notify不会释放锁需要注意的是,运用这种方法,必须要保证t2先执行,也就是首先让t2监听才可以no.原创 2021-02-28 17:32:59 · 109 阅读 · 0 评论 -
ReentrantLock
(1)/** * reentrantlock用于替代synchronized * 由于m1锁定this,只有m1执行完毕的时候,m2才能执行 * 这里是复习synchronized最原始的语义 * * 使用reentrantlock可以完成同样的功能 * 需要注意的是,必须要必须要必须要手动释放锁(重要的事情说三遍) * 使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放 */public class T02_R.原创 2021-02-24 23:59:22 · 103 阅读 · 0 评论 -
AtomicLong和LongAdder
结论:AtomicLong底层CAS原理LongAdder底层线程分组CAS操作原理代理示例:public class T02_AtomicVsSyncVsLongAdder { static long count2 = 0L; static AtomicLong count1 = new AtomicLong(0L); static LongAdder count3 = new LongAdder(); public static void main(St.原创 2021-02-24 23:46:50 · 148 阅读 · 0 评论 -
CAS(无锁优化 自旋 乐观锁)
CAS(修改的值,期望值,更新值)原创 2021-02-24 22:52:37 · 130 阅读 · 0 评论 -
volatile
(1)保证线程可见性---MESI(CPU缓存一致性协议)代码示例:/** * volatile 关键字,使一个变量在多个线程间可见 * A B线程都用到一个变量,java默认是A线程中保留一份copy,这样如果B线程修改了该变量,则A线程未必知道 * 使用volatile关键字,会让所有线程都会读到变量的修改值 * * 在下面的代码中,running是存在于堆内存的t对象中 * 当线程t1开始运行的时候,会把running值从内存中读到t1线程的工作区,在运行过程中直接使用这个原创 2021-02-24 00:15:52 · 107 阅读 · 0 评论 -
synchronized的底层实现
synchronized的底层实现JDK早期的 重量级 - OS后来的改进锁升级的概念:sync (Object)markword 记录这个线程ID (偏向锁)如果线程争用升级为 自旋锁10次以后升级为重量级锁 - OS执行时间短(加锁代码),线程数少,用自旋执行时间长,线程数多,用系统锁...原创 2021-02-23 23:13:48 · 93 阅读 · 0 评论 -
线程---synchronized锁
(1)锁的概念:任何的线程去访问某个对象的时候,看一下这把锁是否属于我,是否由我占有。如果由我占有才可以对这个对象进行操作反之则不操作。代码示例:public class T { private int count = 10; private Object o = new Object(); public void m() { synchronized(o) { //任何线程要执行下面的代码,必须先拿到o的锁 count--;原创 2021-02-23 22:57:50 · 106 阅读 · 0 评论 -
线程的状态
(1)New(2)Runnable里边还有两个状态分别是:Ready就绪和Running运行(3)TimedWaiting等待(4)Waiting等待(3)Blocked堵塞 等待进入同步代码块的锁(3)Teminated结束这里需要说明一下Teminated之后不可以在Start!!!示例图:...原创 2021-02-22 23:51:32 · 220 阅读 · 0 评论 -
线程的启动方式
(1)类继承Thread接口,调用start方法。(2)类继承Thread接口,调用run方法。两者区别:两者程序执行的路径不同。start里的内容和main里的内容可以同时执行,run方法需要先执行它方法里的内容在执行main里的内容。实例代码:public class T01_WhatIsThread { private static class T1 extends Thread { @Override public void run() {原创 2021-02-22 22:31:59 · 194 阅读 · 0 评论 -
线程的概念
(1)一个程序里不同的执行路径,叫做一个线程。原创 2021-02-22 22:24:44 · 121 阅读 · 0 评论 -
线程的3个方法
(1)Thread.sleep();(2)Thread.yield();概念:t1线程在运行,另外t2线程也在运行,当前t1线程在CPU上运行调用了一下yield(),从CPU先离开,另外t2线程可以在这执行。yield的t1进入等待队列中。本质是让出一下CPU,t2线程能否抢到进行执行t1不管。(3)Thread.join();概念:t1线程在运行,另外t2线程也在运行,t1的某一时刻调用了t2.join()。等待t2线程运行完毕,ti1再接着运行。面试题:有3个线程如何保证有序执行完原创 2021-02-22 23:33:55 · 165 阅读 · 0 评论