福州高端品牌网站建设,网站网络优化服务器,凡诺企业网站管理系统,网址导航的优缺点在java中#xff0c;很多时候我们忽略的基本的知识#xff0c;这是很致命的#xff0c;只有搞懂Thread的基础知识#xff0c;才能进一步探索#xff1a;reentrantLock#xff0c;AQS等。
1#xff1a;Thread的线程状态到底有几种#xff1f;
6种#xff1a;
public…在java中很多时候我们忽略的基本的知识这是很致命的只有搞懂Thread的基础知识才能进一步探索reentrantLockAQS等。
1Thread的线程状态到底有几种
6种
public enum State {/*** Thread state for a thread which has not yet started.尚未启动的线程的线程状态。*/NEW,/*** Thread state for a runnable thread. 可运行线程的线程状态。*/RUNNABLE,/*** A thread in the blocked state is waiting for a monitor lock* to enter a synchronized block/method or* reenter a synchronized block/method after calling* 等待获取锁的状态或者等待获取重入锁的状态*/BLOCKED,/*** Thread state for a waiting thread. 线程等待状态调用以下方法都可以使一个线程进入等待状态 -》等待后必须通过notify(),notifyAll()才能唤醒唤醒后才能重新去尝试获取CPU的执行权* ul* li{link Object#wait() Object.wait} with no timeout/li* li{link #join() Thread.join} with no timeout/li* li{link LockSupport#park() LockSupport.park}/li* /ul*/WAITING,/*** Thread state for a waiting thread with a specified waiting time.* 有期限的等待超时等待。以下方法* sleep Thread.sleep* Object#wait(long) * join(long) Thread.join* LockSupport#parkNanos LockSupport.parkNanos* LockSupport#parkUntil LockSupport.parkUntil*/TIMED_WAITING,/*** Thread state for a terminated thread.* 线程结束*/TERMINATED;}
以上源码就解释了什么是阻塞等待但是没有挂起为什么没有挂起状态因为线程挂起这种操作已经过时不建议使用了这里不做过多讨论有人愿意研究的请自行搜索线程挂起。不要搜跟阻塞等待的区别很多都说错了。 2到底如何区分阻塞等待
一切回归原始假设一个场景多个线程任务执行在同一个单核cpu上在我们获取临界资源的时候为了线程安全是要加锁的假设锁是synchronized那么同一时刻只有一个线程任务能获取锁资源那么其它的线程就进入了blocked状态等待获取锁的状态如上代码BLOCKED, 此时这些没有获取到锁的线程有一些条件1他们都是可以随时被CPU上下文切换获取到执行权的。2他们虽然可以获取CPU执行的时间片但是他们无法获取锁。所以被阻塞在这里了。
基于以上两点那么他们处于阻塞状态。而第一个获取到锁的线程是runnable状态。
如果有大量线程为了竞争同一把锁同一临界资源而发生大面积阻塞就会形成线程饥饿。
那什么是等待还是上面的场景加入有一个线程第一个线程获取到了锁那么其它任何线程尝试获取锁都会失败一旦失败调用方法让他们进入等待的话他们就不能再获取到CPU执行权了跟上面所说的阻塞特征的第一点冲突另外他们也不会一直尝试去获取锁了因为他们拿不到CPU执行权相当于一个瘫痪的人没有CPU的帮扶是无法站起来的。 那么他们如何才能站起来继续有机会获取CPU执行权进而获取锁呢 --唤醒-》notify。 所以假如一个线程是wait状态已经如果没有任何线程去唤醒它那它永远是死的如果大量的线程一旦永无机会被唤醒的话将会占用大量内存。 到这里我们一起看一下我sleep和wait的区别
sleep和wait_肥春勿扰的博客-CSDN博客