![](https://img-blog.csdnimg.cn/20190927151124774.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
JAVA多线程知识整理
JAVA多线程知识整理
迟到的help
这个作者很懒,什么都没留下…
展开
-
简单理解AQS ( 抽象的队列同步器)
AbstractQueuedSynchronizer 类如其名,抽象的队列式的同步器, AQS 定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的 ReentrantLock/Semaphore/CountDownLatch。它维护了一个 volatile int state(代表共享资源)和一个 FIFO(先进先出)线程等待队列(多线程争用资源被阻塞时会进入此队列)。这里 volatile 是核心关键词,具体 volatile 的语义,在此不述。 state 的访问方.原创 2020-06-03 22:28:10 · 361 阅读 · 0 评论 -
Java 中用到的线程调度方式以及调度算法
线程调度方式抢占式调度抢占式调度指的是每条线程执行的时间、线程的切换都由系统控制,系统控制指的是在系统某种运行机制下,可能每条线程都分同样的执行时间片,也可能是某些线程执行的时间片较长,甚至某些线程得不到执行的时间片。在这种机制下,一个线程的堵塞不会导致整个进程堵塞。协同式调度协同式调度指某一线程执行完后主动通知系统切换到另一线程上执行,这种模式就像接力赛一样,一个人跑完自己的路程就把接力棒交接给下一个人,下个人继续往下跑。线程的执行时间由线程本身控制,线程切换可以预知,不存在多线程同步问题,但原创 2020-06-02 23:47:00 · 4305 阅读 · 1 评论 -
synchronized 和 ReentrantLock 的区别
两者的共同点:1. 都是用来协调多线程对共享对象、变量的访问2. 都是可重入锁,同一线程可以多次获得同一个锁3. 都保证了可见性和互斥性两者的不同点:1. ReentrantLock 显示的获得、释放锁(手动挡), synchronized 隐式获得释放锁(自动挡)2. ReentrantLock 可响应中断、可轮回, synchronized 是不可以响应中断的,为处理锁的不可用性提供了更高的灵活性3. ReentrantLock 是 API 级别的, synchronized 是 J原创 2020-06-02 23:06:43 · 456 阅读 · 0 评论 -
sleep 与 wait 区别
1. 对于 sleep()方法,我们首先要知道该方法是属于 Thread 类中的。而 wait()方法,则是属于Object 类中的。2. sleep()方法导致了程序暂停执行指定的时间,让出 cpu 给其他线程,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。3. 在调用 sleep()方法的过程中, 线程不会释放对象锁。4. 而当调用 wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用 notify()方法后本线程才进入对象锁定池准备获原创 2020-06-02 22:32:18 · 157 阅读 · 0 评论 -
自旋锁
自旋锁的提出背景由于在多处理器环境中某些资源的有限性,有时需要互斥访问(mutual exclusion),这时候就需要引入锁的概念,只有获取了锁的线程才能够对资源进行访问,由于多线程的核心是CPU的时间分片,所以同一时刻只能有一个线程获取到锁。那么就面临一个问题,那么没有获取到锁的线程应该怎么办?通常有两种处理方式:一种是没有获取到锁的线程就一直循环等待判断该资源是否已经释放锁,这种锁叫做自旋锁,它不用将线程阻塞起来(NON-BLOCKING);还有一种处理方式就是把自己阻塞起来,等待重新调度请求原创 2020-06-02 01:32:38 · 999 阅读 · 0 评论 -
CAS无锁机制
什么是CAS?CAS:Compare and Swap,即比较再交换。jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。CAS算法理解对CAS的理解,CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什.原创 2020-06-02 01:04:18 · 741 阅读 · 0 评论 -
读写锁
相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些。假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。这就需要一个读/写锁来解决这个问题。Java5在java.util.concurrent包中已经包含了读写锁。原创 2020-06-02 00:09:09 · 174 阅读 · 0 评论 -
重入锁
锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些已经写好提供的锁为我们开发提供了便利。重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响,锁向下进行了传递。在JAVA环境下 ReentrantLock 和synchronized 都是 可重入锁。import java.util.concurrent.locks.ReentrantLock;pub原创 2020-06-01 23:38:10 · 109 阅读 · 0 评论 -
悲观锁与乐观锁
悲观锁总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。以淘宝下单过程中扣减库存的需求说明一下悲观锁的使用:悲观锁使用以上,在对id.原创 2020-06-01 23:04:22 · 185 阅读 · 0 评论 -
合理配置线程池
要想合理的配置线程池,就必须首先分析任务特性,可以从以下几个角度来进行分析:一、任务的性质:CPU密集型任务,IO密集型任务和混合型任务。花费了绝大多数时间在计算上称为计算密集型(CPU密集型)computer-bound花费了绝大多数时间在等待I/O上称为I/O密集型,I/O-boundCPU密集型时,任务可以少配置线程数,大概和机器的cpu核数相当,这样可以使得每个线程都在执行任务。 IO密集型任务则由于需要等待IO操作,线程并不是一直在执行任务,则配置尽可能多的线程,如2*Ncpu。原创 2020-05-26 23:48:08 · 146 阅读 · 1 评论 -
线程池原理分析
什么是线程池?Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池。在开发过程中,合理地使用线程池能够带来3个好处。第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。第三:提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。但是,要做到合理利用线程池,必须对其实现原理了如指掌。原创 2020-05-25 23:51:12 · 623 阅读 · 0 评论 -
多线程之并发队列
并发队列在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue。ConcurrentLinkedDequeConcurrentLinkedQueue:是一个适用于高并发场景下的队列,通过无锁的方式,实现了高并发状态下的高性能,通常ConcurrentLinkedQueue性能好于BlockingQueue.它是一个基于链接节点的无界线程安全队列。该队列的元素..原创 2020-05-25 22:39:07 · 485 阅读 · 0 评论 -
了解多线程常用的并发包
CountDownLatchCountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。public class Test002 { public static void main(String[] args) throws InterruptedException { System.out.println("等待子线程原创 2020-05-25 22:30:32 · 276 阅读 · 0 评论 -
为什么Vector、HasTable是线程安全的?ConcurrentHashMap 分段锁?
Vector源码类add方法:get方法:HashTable源码类put方法:get方法:他们都有一个共同点都加了同步函数,来保证线程安全因为HashTable的读写都是同步的,所以多线程效率非常低,jdk1.5后出现了他的替代品ConcurrentHashMapConcurrentMap接口下有俩个重要的实现:ConcurrentHashMapConcurrentskipListMap(支持并发排序功能。弥补ConcurrentHashMa...原创 2020-05-18 23:38:37 · 793 阅读 · 0 评论 -
什么是ThreadLocal
ThreadLocal提高一个线程的局部变量,访问某个线程拥有自己局部变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。ThreadLocal的接口方法ThreadLocal类接口很简单,只有4个方法:void set(Object value)设置当前线程的线程局部变量的值。public Object get()该方法返回当前线程所对应的线程局部变量。p原创 2020-05-09 00:05:31 · 186 阅读 · 0 评论 -
如何停止线程
停止线程思路1. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。2. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。package com.Test;public class ThreadTest1 extends Thread { boolean flag = true; @Override public void run() { System...原创 2020-05-08 23:16:35 · 271 阅读 · 0 评论 -
多线程Lock锁
在 jdk1.5 之后,并发包中新增了 Lock 接口(以及相关实现类)用来实现锁功能,Lock 接口提供了与 synchronized 关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。Lock 锁与 synchronized 同步锁的区别lock锁:手动挡,手动上锁,手动释放锁,灵活性高synchronized同步锁:自动挡,代码开始自动上锁,代码结束自动释放锁,缺点效率低、...原创 2020-05-05 02:02:55 · 260 阅读 · 0 评论 -
多线程之间通讯
什么是多线程之间通讯?多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同。现在假设有这么一个需求:第一个线程写入(input)用户,另一个线程取读取(out)用户.实现读一个,写一个操作。代码:package com.Thread.test;public class Res { public String name; public ...原创 2020-05-05 01:12:11 · 222 阅读 · 0 评论 -
多线程 Volatile 关键字
Volatile 关键字的作用是变量在多个线程之间可见,但不保证数据的原子性代码:package com.jvm.test;class ThreadVolatileDemo extends Thread { public boolean flag = true; @Override public void run() { System.out...原创 2020-05-04 00:55:44 · 176 阅读 · 0 评论 -
java内存模型JMM
这里有个常见的误区:java内存结构指的是内存分配的概念(JVM),堆栈方法区等;java内存模型指的是多线程可见性 (JMM),决定了一个线程与另一个线程是否可见;从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量...原创 2020-05-04 00:28:41 · 94 阅读 · 0 评论 -
多线程三大特性
多线程有三大特性分别是:原子性、可见性、有序性什么是原子性?即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。一个很经典的例子就是银行账户转账问题:比如从账户A向账户B转1000元,那么必然包括2个操作:从账户A减去1000元,往账户B加上1000元。这2个操作必须要具备原子性才能保证不出现一些意外的问题。我们操作数据也是如此,比如i = i+1;...原创 2020-05-04 00:01:18 · 163 阅读 · 0 评论 -
多线程死锁现象
什么是多线程死锁?死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。死锁代码:package com.jvm.test;class ThreadTrain2 implements Runnable { public ...原创 2020-05-03 23:50:03 · 251 阅读 · 0 评论 -
线程安全问题
当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题。案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。代码:package com.jvm.test;class ThreadTrain1 implements Runnable { private int...原创 2020-05-03 23:18:13 · 245 阅读 · 0 评论 -
join()方法作用
join作用是让其他线程变为等待, t1.join();// 让其他线程变为等待,直到当前t1线程执行完毕,才释放。thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。例子:public class MyThread implements Runn...原创 2020-05-02 23:28:14 · 1415 阅读 · 0 评论 -
线程生命周期(状态)
新建状态当用new操作符创建一个线程时, 例如new Thread(r),线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码就绪状态一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当s...原创 2020-05-02 23:04:25 · 96 阅读 · 0 评论 -
守护线程
Java中有两种线程:一种是用户线程,另一种是守护线程。用户线程是指用户自定义创建的线程,主线程停止,用户线程不会停止 守护线程是指当进程不存在或主线程停止,守护线程也会被停止。与主线程共死使用setDaemon(true)方法可以将线程设置为守护线程//什么是守护线程? 守护线程 进程线程(主线程挂了) 守护线程也会被自动销毁.public class Test3 { ...原创 2020-05-02 22:56:10 · 183 阅读 · 0 评论 -
多线程的创建方式
第一种继承Thread类 重写run方法第二种实现Runnable接口,重写run方法此方法需要new Thread(),将t传入,才能条用start方法启动线程第三种使用匿名内部类方式使用继承Thread类还是使用实现Runnable接口好?实现Runnable接口避免了单继承的局限性,java单继承多实现...原创 2020-05-02 22:22:07 · 97 阅读 · 0 评论 -
什么是多线程?
什么是进程?进程就是正在运行的程序,他是线程的集合。什么是线程?线程就是正在独立运行一条执行路径。什么是多线程?多线程就是为了提高程序的效率什么是同步?代码从上往下执行,单线程什么是异步?线程间相互不影响,基本同时执行...原创 2020-05-02 21:46:59 · 188 阅读 · 0 评论