Java并发编程
文章平均质量分 59
Java并发编程
weixin_46248981
这个作者很懒,什么都没留下…
展开
-
利用生产者与消费者模型实现线程池Java
实际编码中经常遇到处理并发的场景,下面是一种用生产者-消费者模型实现的线程池,可以实现并发处理功能。也可以不使用wait(),notify(),而是直接用BlockingQueue来实现。import java.util.LinkedList;import java.util.Queue; public class WorkerPool { // 线程池Worker数量 private static final int WORKER_COUNT = 10; /转载 2021-11-08 16:17:29 · 288 阅读 · 0 评论 -
多线程下i++和++i操作如何保证线程安全
https://blog.csdn.net/zbw18297786698/article/details/53420780volaitilevolatile关键字解决的是多线程间共享变量的可见性问题,而保证不了多线程共享变量原子性问题,对于多线程的i++、++i依然会存在多线程问题,volatile是无法解决的。Thred1 Thread2:r1 = i; r3 = i; //读取i值r2 = r1+1; r4 = r3+1; //i值加1i = r2;转载 2021-09-11 10:14:16 · 978 阅读 · 0 评论 -
Java的进程间同步模型(生产者消费者、读写者、哲学家就餐)
https://blog.csdn.net/qq_40550018/article/details/87859399//商品类public class Goods { private int id; private String name; public Goods(int id, String name) { this.id = id; this.name = name; }}//消费者类public class Producer转载 2021-08-25 11:59:08 · 97 阅读 · 0 评论 -
写时复制了解吗(并发场景下)
写时复制(Copy On Write)核心思想是,如果有多个调用者同时请求相同资源(如内存或磁盘上的数据存储),会共同获取相同的指针指向相同的资源,直到某个调用者视图修改资源的内容时,系统才会真正复制一份专用副本给该调用者,而其他调用者所见到的最初的资源仍然保持不变,这个过程对其他调用者是透明的。此作法的主要优点是如果调用者没有修改该资源,就不会该副本被建立,因此多个调用者只是读取操作时可以共享同一份资源。Java中的COWJDK中的CopyOnWriteArrayList/CopyOnWriteA转载 2021-07-31 19:27:49 · 262 阅读 · 0 评论 -
ReentrantReadWriteLock
1.什么是读写锁读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性比一般的排他锁有了很大提升2.读写锁的特性公平性:支持非公平和公平的获取方式,吞吐量还是非公平由于公平。重进入:该锁支持重进入,以读写线程为例,读线程在获取了读锁之后,能够再次获取读锁,而线程在获取了写锁之后能够再次获取读写锁,同时也可以获取读锁。锁降级:遵循获取写锁,获取读锁在释放写锁的次序,写锁能够降级成读锁。3.读写锁的实现int变量按位切割使用。高16位表示读,低16表示写。4.锁降级原创 2021-07-17 22:45:10 · 34 阅读 · 0 评论 -
双重检查实现单例模式
public class Singleton{ private static volatile Singleton singleton; private Singleton(){} public Singleton getInstance(){ if(singleton==null){ synchronized(Singleton.class){ if(singleton==null){ singleton = new Singleton(); } } }原创 2021-07-08 16:32:30 · 114 阅读 · 0 评论 -
手写单例模式
1.为什么要有单例模式实际编程应用场景中,有一些对象其实我们只需要一个,比如线程池对象、缓存、系统全局配置对象等。这样可以保证一个在全局使用的类不被频繁地创建与销毁,节省系统资源。2.实现单例模式的几个要点首先要保证全局只有一个类的实例要保证这一点,至少类的构造器要私有化。单例的类只能自己创建自己的实例因为,构造器私有了,但是要一个实例,只能自己创建。单例类必须提供自己唯一实例给其他类就是要一个有公共方法返回该单例类的唯一实例。3.单例模式的6种实现1.饿汉式——静态变量方式(线程原创 2021-07-08 16:13:47 · 49 阅读 · 0 评论 -
volatile了解吗?(面试)
1.什么是volatile呢volatile是Java虚拟机提供的最轻量级的同步机制2.volatile的两大特性(两大语义)可见性和有序性,没有原子性。3.volatile的可见性如何实现volatile定义:当volatile执行写操作后,JMM会把工作内存中的最新变量值强制刷新到主内存中并且写操作会让其他线程中的变量缓存无效化这样,其他线程使用缓存时,发现本地工作内存中此变量无效,便从主内存中获取,这样获取到的变量就是最新的值,实现了线程的可见性。4.volatile如何实现有序原创 2021-07-07 17:29:36 · 134 阅读 · 0 评论 -
Java内存模型(JMM)了解吗
1. Java的内存模型是什么Java的内存模型JMM是一个抽象概念,实际上并不存在。它涵盖了缓存、写缓冲区、寄存器以及其他硬件和编译器优化。2.JMM的作用是什么并发编程中需要解决两个关键问题就是通信和同步。线程的通信机制有两种:共享内存和消息传递。Java的并发模型采用是共享内存模型。所以JMM主要解决的是多线程之间的通信问题。3.JMM的通信过程了解吗如果线程A和B之间要通信,必须经历下面两个步骤:线程A把本地内存A中更新过的共享变量刷新到主内存中线程B到主内存中去读取线程A原创 2021-07-07 16:28:28 · 58 阅读 · 0 评论 -
为什么要使用多线程呢,已经多线程遇到的挑战
1.为什么要使用多线程多线程可以减少上下文切换的开销多线程机制可以大大提高系统整体的并发能力和性能单核时代:提高CPU和IO设备的综合利用率多核时代:提高CPU利用率2.使用多线程会带来什么问题呢?内存泄漏、上下文切换、死锁。3.什么是内存泄漏内存泄漏即该释放的内存没有被及时的释放,一直被某个或某些实例所持有却不在再使用导致GC不能回收。4.什么是上下文切换当前任务执行完CPU时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。任务从保原创 2021-07-06 11:33:09 · 153 阅读 · 0 评论 -
常见的并发工具类知道哪些
在JDK的并发包里提供了几个非常有用的并发工具类。CountDownLatch、CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段。Exchanger工具类则提供了在线程间交换数据的手段。等待多线程完成的CountDowmLatchCountDownLatch允许一个或多个线程等待其他线程完成操作。在JDK1.5之后的并发包中提供了CountDowmLatch可以实现join的功能,并且比join功能更多。public class CountDowmLatchTest原创 2021-05-25 17:08:40 · 425 阅读 · 1 评论 -
对AQS有什么了解?面试专用
1.什么是AQSAQS的全称是AbstractQueuedSynchronizer。叫做队列同步器。它是构建锁和其他同步组件的基本框架。主要定义了一个int变量state来表示同步状态。主要通过内置的FIFO队列来完成资源获取线程的排队过程。同步器的主要实现方式是继承。子类通过继承同步器然后并实现它的抽象方法来管理同步状态。主要用到的方法有:getState()setState(int newState)compareAndSetState(int expect,int update)原创 2021-05-25 16:54:13 · 125 阅读 · 2 评论 -
Conditon接口
任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object上),主要包括wait()、wait(longe timeout)、notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,但是这两者在使用方法以及功能特性上还是有差别的。Condition接口与实例Condition定义了等待/通知两种类型的方法,当前线程调原创 2021-04-26 22:14:54 · 48 阅读 · 0 评论 -
LockSupport工具
LockSupport定义了一组以park开头的方法用来阻塞当前线程。void park()。阻塞当前线程,如果调用unpark(Thread thread)方法或者当前线程被中断,才能从park()方法返回。-void parkNanos(long nanos)。阻塞当前线程,最长不超过nanos纳秒,返回条件在park()的基础上增加了超时返回。void parkUntil(long deadline)。阻塞当前线程,知道deadline时间void unpark(Thread thre原创 2021-04-26 21:11:40 · 34 阅读 · 0 评论 -
读写锁
1.什么是读写锁读写锁在同一时刻可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。Java并发包提供读写锁的实现是ReentrantReadWriteLock。ReentrantReadWriteLock的特性:公平性选择:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。重进入:该锁支持重进入,以读写线程为例:该线程在获取了读锁之后,能够再次获取读锁。原创 2021-04-26 21:05:22 · 690 阅读 · 0 评论 -
重入锁ReentrantLock
重入锁ReentrantLock,就是支持重进入的锁,它表示该锁能够支持一个线程对资源重复加锁。除此之外,该锁的还支持获取锁时的公平和非公平选择。1.实现重进入重进入是指任意线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞,该特性的实现需要解决两个问题:线程再次获锁。锁需要去识别锁的线程是否为当前占据锁的线程,如果是,则再次成功获取。锁的最终释放。线程重复n此获取锁,随后再第n此释放该锁后,其他线程能够获取到该锁。锁的最终释放要求锁对于获取进行计数自增,计数表示当前锁被重复获取的次数,而锁被释原创 2021-04-26 16:33:07 · 59 阅读 · 0 评论 -
介绍一下Atomic原子类
Atomic类都存放在java.util.concurrent.atomic下JUC包中的原子类是哪四类基本数据类型、数组类型、引用类型、对象属性修改类型。1.基本数据类型使用原子的方式更新基本类型AtomicInteger:整型原子类AtomicLong:长整型原子类AtomicBoolean:布尔型原子类2.数组类型使用原子的方式更新数组里的某个元素AtomicIntegerArray:整型数组原子类AtomicLongeArray:长整型数组原子类AtomicRefer原创 2021-04-26 15:12:51 · 103 阅读 · 0 评论 -
说说synchronized关键字和volatile关键字的区别
synchronized关键字和volatile关键字是两个互补的存在。volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized 关键字可以修饰方法以及代码块。volatile关键字可以保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。volatile关键字主要用于解决变量在多个线程之间的可见性,而synchronized关键字解决的是多个线程之原创 2021-04-25 21:54:21 · 124 阅读 · 0 评论 -
说说并发与并行的区别
并发:同一时间段,多个任务都在执行(的那位时间内不一定同时执行)。并行:单位时间内,多个任务同时执行。原创 2021-04-25 20:39:03 · 81 阅读 · 0 评论 -
在Java中守护线程和本地线程区别
Java中的线程分为两种:守护线程(Daemon)和用户线程(User)。任何线程都可以设置守护线程和用户线程,通过方法Thread.setDaemon(boolean flag),传入true。则把该线程设置为守护线程,反之则为用户线程。Thread.setDaemon()必须在Thread.start()之前调用。否则运行时会抛出异常。区别:唯一的区别是判断虚拟机(JVM)何时离开,Daemon是为其他线程提供服务,如果全部User Thread撤离。JVM的垃圾回收线程是守护线程,当所有线程已原创 2021-04-25 20:36:49 · 182 阅读 · 0 评论 -
Java内存模型,双重锁定
1.Java内存模型的基础1.1并发编程模型的两个关键问题在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步。通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递。在共享内存的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信。在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息来进行显式通信。同步是指程序中用于控制不同线程间操作发送相对顺序的机制。在共享内存并发模型里,同步是显式原创 2021-04-23 22:55:01 · 74 阅读 · 0 评论 -
原子操作的实现原理
1.什么是原子操作原子本意是不能被进一步分割的最小粒子,而原子操作就意味着不可被中断的一个或一系列操作。原子操作的常见术语缓存行:Cache line 缓存的最小操作单位比较并交换:Compare and Swap。CAS操作需要输入两个数值,一个旧值(期望操作前的值)和一个新值,在操作期间先比较旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换。CPU流水线:CPU pipeline。CPU流水线的工作发生就像是工业生产上的装配流水线,在CPU中由5~6个不同功能的电路单元组原创 2021-04-23 11:50:17 · 381 阅读 · 0 评论 -
什么是synchronized?实现原理?
1什么是synchronized多线程并发编程中synchronized一直是元老级角色,很多人都会称呼它为重量级锁。但是,随着JDK1.6之后对synchronized进行了优化之后,并没有那么重了。本文基于JDK1.6介绍了synchronized为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁,以及锁的存储结构和升级过程。synchronized实现同步的基础:Java中的每一个对象都可以作为锁。对于普通同步方法,锁是当前实例对象。对于静态同步方法,锁是当前类的Class对象原创 2021-04-21 22:59:07 · 136 阅读 · 0 评论 -
volatile关键字的作用?实现原理?
1.什么是volatilevolatile是轻量级synchronized。它在多处理器开发中保证了共享变量的可见性。可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。如果volatile使用恰当,它比synchronized的使用和执行成本更低,它不会引起线程上下文的切换和调度。2.实现原理Java语言规范第三版中对volatile的定义:Java编程语言运行线程访问共享变量。为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。Java提供了vo原创 2021-04-21 17:55:29 · 222 阅读 · 0 评论 -
什么是AQS?AQS有什么作用?常见的基于AQS的组件有哪些?
1.什么是AQSAQS队列同步器(AbstractQueuedSynchronizer),是用来构建锁或者其他同步组件的基础框架。它使用了一个int的成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。同步器的主要使用方式是继承,子类通过基础同步器并实现它的抽象方法来管理同步状态,在抽象方法的实现过程中免不了对同步状态进行更改,这时需要使用同步器提供的三个方法(getState()、setState(int newState)和compareAndSetState(int exp原创 2021-04-19 22:22:45 · 3398 阅读 · 0 评论 -
什么是ThreadLocal?实现原理?
基于JDK1.81.ThreadLocal有什么用?2.ThreadLocal为什么能实现每个线程能有一个独立的变量副本3.每个线程的变量副本存储位置在哪儿4.变量副本是如何从共享变量中复制出来的1.ThreadLocal有什么用ThreadLocal是为了各个线程都有一份自己独立的变量(对象),而不是用来解决共享对象的多线程访问问题的。...原创 2021-04-13 11:37:51 · 119 阅读 · 0 评论 -
保证线程同步的机制有哪些——看操作系统即可,简单了解
线程同步的方式:1.同步方法2.同步代码块3.使用重入锁实现线程同步(ReentrantKLock)4.使用特殊域变量(volatile)实现同步(每次重新计算,安全但并非一致)5.使用原子变量实现线程同步(AtomicInteger(乐观锁))6.使用阻塞队列实现线程同步(BlockingQueue add()、offer()、put())1.同步方法即有synchronized关键字修饰的方法。由于Java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。调用该方原创 2021-04-12 20:45:37 · 312 阅读 · 0 评论 -
Java中如何创建一个线程?
1.继承Thread类实现,重写run()2.实现Runnable接口,重写run()方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target3.通过Callable和FutureTask创建线程4.通过线程池创建线程前面两种可以归结为一类:没有返回值,通过重写run(),run()的返回值是void,所以没有办法返回结果。后面两种可以归结为一类:有返回值,通过Callable接口,就要实现call(),这个方法的返回值是Object,所以返回的结果可以放在Objec原创 2021-04-12 19:48:29 · 1498 阅读 · 0 评论 -
线程池面试题
Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池。1.线程池的好处降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高相应速度。任务可以不需要等到线程创建就能立即执行。提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。但是要做到合理利用线程池,必须对其实现原理了如指掌。2.线程池的实现原理(当向线程池提交任务后,线程池如何处理)向线程池提原创 2021-03-27 11:01:00 · 127 阅读 · 0 评论 -
线程的生命周期相关问题
1.区别进程是程序执行的基本单位。一个进程执行时能够有多条线程。多条线程共享同个进程的堆和方法区。每个线程有自己的Java方法栈和本地方法栈程序计数器。2.Java方法栈:在每个Java方法调用时候就会创建一个栈帧存储局部变量表、操作数栈, 常量池应用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧从Java虚拟机栈中入栈和出栈的过程。3.程序计数器为什么是私有的?程序通过改变程序计数器来一次读取指令,从而实现代码的流程控制。如:顺序控制、循环控制、异常处理。在多线程切换时,程序计数器会原创 2021-03-26 11:10:23 · 74 阅读 · 0 评论 -
死锁
1.什么是死锁 在多线程的情况下,多个线程为了争夺资源而造成的程序无法继续执行的现象。 例如:A线程获取了了1资源的锁,而B线程获取了2资源的锁,这时候A线程又想获取2资源,而B线程又想获取1资源。然后他们就会一直等待对方释放相应的锁,并且不释放自己所持有的锁。2.什么情况下会产生死锁呢互斥资源:该资源在同一时间只能被一个线程占用请求与保持条件:在获取新的资源时候,不会释放已占用的资源不剥夺条件:对于线程已经占用的资源,不能够随意剥夺循环等待条件:若干线程之间形成了循环等待的资源的情况原创 2021-03-25 22:18:54 · 44 阅读 · 1 评论