JAVA线程知识整理

来源:互联网 发布:windows rt 升级 编辑:程序博客网 时间:2024/05/17 09:27

最近结合《java编程思想》和一些网上的博客来重新研究了一下线程的状态,这里做个小小的总结,为大家也为自己巩固基础知识。

部分参考Java中Wait、Sleep和Yield方法的区别

线程几种基本状态

一般来说,线程可以有四种状态:

(1)新建new:当线程被创建时,它只会短暂地处于这种状态,此时它已经分配了必需的系统资源,并执行了初始化。此刻线程已经有资格获得CPU时间了,之后调度器将把这个线程转变为可运行状态或阻塞状态

(2)可运行(Runnable):这种状态下,只要调度器把时间片分配给线程,线程就可以运行,也就是说,在任意时刻,线程可以运行也可以不运行。只要调度器能分配时间片给线程,它就可以运行,如调用了yeild(方法后)

(3)死亡(Dead):处于死亡状态的线程将不再是可调度的,并且再也不会得到CPU时间,它的任务已经结束。通常死亡的方式是从run()方法返回,但是任务的线程还可以被中断

(4)堵塞(Blocked):线程可以运行,但是有某种东西阻碍了它。若线程处于阻塞状态,调度机制可以简单地跳过它,不给他分配任何CPU时间,除非线程再次进入“可运行”状态,否则不会采取任何操作

堵塞

堵塞状态是这四种状态中最复杂的,线程的堵塞可能是由下面四个方面的原因造成的:

(1)调用sleep(毫秒数),使线程进入睡眠状态,在指定时间内,这个线程是不会运行的(但是没有释放锁)

(2)用wait()暂停了线程的执行,除非线程收到notify()或者notifyAll()消息,否则不会编程可运行

(3)线程正在等候一些IO操作完成

(4)线程试图调用另一个对象的同步方法,但是没有获取该方法的锁

wait()、sleep()、yeild()的区别

(1)sleep()和yeild()是定义在Thread中,而wait()定义在Object中

(2)调用了sleep()或wait()之后,线程将进入阻塞状态;而调用yeild(),意思是放弃当前CPU时间,之后线程进入可运行状态。与wait()和sleep()方法有一些区别,它仅仅释放线程所占有的CPU资源,从而让其他线程有机会运行,但是并不能保证某个特定的线程能够获得CPU资源。谁能获得CPU完全取决于调度器,在有些情况下调用yield方法的线程甚至会再次得到CPU资源

(3)Thread.sleep()方法是一个静态方法,作用在当前线程上;但是wait方法是一个实例方法,并且只能在其他线程调用本实例的notify()方法时被唤醒。当调用了sleep(1000)时,该线程在这1000ms内处于阻塞状态,但是不释放其所拥有的资源锁,即时间一到自动回到原来的使用场景;而wait()则用于线程之间的通信,当一个线程调用wait()之后,代表它释放了对CPU和资源锁的占有权,直到在其他某个线程内的notify()或notifyAll()被调用,它才有机会重新进入运行状态

(4)yield()和sleep()的主要区别在于,yield方法会临时暂停当前正在执行的线程,来让有同样优先级的正在等待的线程有机会执行。如果没有正在等待的线程,或者所有正在等待的线程的优先级都比较低,那么该线程会继续运行。执行了yield方法的线程什么时候会继续运行由线程调度器来决定,不同的厂商可能有不同的行为。yield方法不保证当前的线程会暂停或者停止,但是可以保证当前线程在调用yield方法时会放弃CPU。

原创粉丝点击