![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
多线程
探索多线程奥秘
上士闻道~勤而行之
这个作者很懒,什么都没留下…
展开
-
哪些指令不能重排:Happen-Before规则
虽然java虚拟机和执行系统会对指令进行一定的重排,但是指令重排是有原则的,并非所有的指令都可以随便改变执行位置,以下这些基本原则是指令重排不可违背的:程序顺序原则:一个线程内保证语义的串行性。 volatile规则:volatile变量的写先与读发生,这保证了volatile变量的可见性。 锁规则:解锁(unlock)必然发生在随后的加锁(lock)前。 传递性:A先与B,B先与C,那么A必然先于C。 线程的start()方法先于它的每一个动作。 线程的所有操作先于线程的终结(Thread.原创 2021-02-01 21:27:21 · 172 阅读 · 0 评论 -
JMM中原子性,可见性,有序性
原子性(Atomicity):原子性是指一个操作是不可中断的。即使是多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。可见性(Visibility):可见性是指当一个线程修改了某一个共享变量的值时,其他线程是否能够立即知道这个修改。有序性(Ordering): 对于一个线程的执行代码而言,我们总是习惯地认为代码是从前往后依次执行的;这么理解不完全正确,因为就一个线程而言,确实会表现成这样。但是。在并发时,程序的执行可能就会出现乱序。...原创 2021-02-01 21:16:29 · 364 阅读 · 0 评论 -
死锁,饥饿和活锁
死锁,饥饿和活锁都属于多线程的活跃性问题。如果发现这几种情况,那么相关线程就不再活跃了,也就是说线程很难再继续执行下去了。死锁:大家都不愿意释放自己的资源,这个状态永久持续下去,那么谁都无法执行。饥饿:是指某一个或多个线程因为种种原因无法获得所需要的资源,导致一直无法执行。比如它的线程优先级可能太低,而高优先级的线程不断抢占它需要的资源,导致低优先级线程无法工作。活锁:多个线程都主动将资源释放给他人使用,那么就会导致资源不断地在两个线程间跳动,而没有一个线程可以同时拿到所有资源正常执行。...原创 2021-01-31 22:49:49 · 140 阅读 · 0 评论 -
Jstack线程状态BLOCKED/TIMED_WAITING/WAITING解释
一、线程5种状态新建状态(New) 新创建了一个线程对象。 就绪状态(Runnable) 线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。 运行状态(Running) 就绪状态的线程获取了CPU,执行程序代码。 阻塞状态(Blocked) 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就...转载 2019-08-02 10:30:00 · 498 阅读 · 0 评论 -
线程中的yield()方法
转载 https://blog.csdn.net/Terrence_he/article/details/78333753Thread.yield()方法作用是:暂停当前正在执行的线程对象(及放弃当前拥有的cup资源),并执行其他线程。yield()做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适...转载 2018-09-05 14:25:12 · 743 阅读 · 0 评论 -
设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1
public class Locktes2 { private int j; public static void main(String[] args){ Locktes2 locktes2 = new Locktes2(); Inc inc = locktes2.new Inc(); Dec dec = locktes2.new Dec(); for(int i = 0;i < ...原创 2018-04-08 09:51:39 · 207 阅读 · 0 评论 -
同步和异步有何异同
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。 当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。...原创 2018-04-08 09:51:50 · 109 阅读 · 0 评论 -
BlockingQueue
a.ArrayBlockingQueue ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,这点尤其不同于LinkedBlockingQueueArrayBlockingQueue和LinkedBlockingQueue间还有一个明显的不同之处在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例,而后者则会生成一个...原创 2018-04-06 09:42:01 · 105 阅读 · 0 评论 -
java 中有几种方法可以实现一个线程
a.继承Thread类 new Thread( piblic void run(){ } ).start(); b.实现Runnable接口 new Thread(new Runnable(){ public void run(){ } } ).start();注意:启动线程是start方法!...原创 2018-04-06 09:42:13 · 216 阅读 · 0 评论 -
volatile
使用volatile关键字的场景: synchronized关键字是防止多个线程同时执行一段代码,那么就会很影响程序执行效率,而volatile关键字在某些情况下性能要 优于synchronized,因为volatile关键字无法保证操作的原子性。 通常来说,使用volatile必须具备以下2个条件: 1)对变量的写操作不依赖于当前值 2)该变量没有包含在具有其他变量的不变式中可参考: http:...原创 2018-04-06 09:42:56 · 88 阅读 · 0 评论 -
sleep() 和 wait() 区别
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复;调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致程本线放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。...原创 2018-04-06 10:39:34 · 83 阅读 · 0 评论 -
JAVA线程有哪些状态,这些状态之间是如何转化的?
新建(new):新创建了一个线程对象。可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。运行(running):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu...原创 2018-05-11 14:07:09 · 2189 阅读 · 0 评论 -
多线程-阻塞与非阻塞概念
临界区:临界区用来表示一种公共资源或者说共享数据,可以被多个线程使用。但是每一次只能有一个线程使用它,一旦临界资源被占用,其他线程要想使用这个资源就必须等待。阻塞:比如一个线程占用了临界区资源,那么其他所有需要这个资源的线程就必须在这个临界区中等待。等待会导致线程挂起,这种情况就是阻塞。非阻塞:强调没有一个线程可以妨碍其他线程执行,所有的线程都会尝试不断向前执行。...原创 2021-01-31 22:01:54 · 896 阅读 · 0 评论