Java线程(线程)
1|0线程与进程的区别
进程是操作系统分配资源的最小单元,线程是操作系统调度的最小单元。
一个程序至少有一个进程,一个进程至少有一个线程。
2|0
3|0创建线程的三种方式
继承Thread类
- 定义Thread类的子类,重写该类的run方法。
-
创建Thread子类的实例,即创建了线程对象(new project)
-
调用线程对象的start()方法来启动该线程(project.start();)
实现Runnable接口
-
定义runnable接口的实现类,并重写该接口的run方法
-
创建该实现类的实例,并以该实例作为Thread的target来创建Thread对象(
Thread t1 = new Thread(myThreandImpl)
),这个thread对象才是真正的线程对象 -
调用线程对象的start()方法来启动该线程
实现Callable接口
-
创建Callable接口的实现类,并实现call()方法,该call方法将作为线程执行体,并且有返回值。
-
创建Callable实现类的实例对象,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call方法的返回值。
-
使用FutureTask对象作为Thread对象的Target,创建并启动新线程
-
调用TutureTask对象的get()方法来获得子线程执行结束后的返回值。
4|0三种创建线程的优缺点
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
-
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
-
Runnable和Callable的区别:
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以,因为run方法本身没有抛出异常,所以自定义的线程类在重写run的时候也无法抛出异常
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
5|0start()和run()方法的区别
6|0线程生命周期
当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。 在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞 (Blocked)和死亡(Dead)5 种状态。
尤其是当线程启动以后,它不可能一直"霸占"着 CPU 独自 运行,所以 CPU 需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。
6|1线程状态之新建状态New
当程序使用 new 关键字创建了一个线程之后,该线程就处于新建状态,此时仅由 JVM 为其分配 内存,并初始化其成员变量的值。
6|2线程状态之就绪状态Runnable
当线程对象调用了 start()方法之后,该线程处于就绪状态。Java 虚拟机会为其创建方法调用栈和 程序计数器,等待调度运行。
6|3线程状态之运行状态Running
如果处于就绪状态的线程获得了 CPU,开始执行 run()方法的线程执行体,则该线程处于运行状态。
6|4线程状态之阻塞状态Blocked
阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice,暂时停止运行。 直到线程进入可运行(runnable)状态,才有机会再次获得 cpu timeslice 转到运行(running)状 态。阻塞的情况分三种:
-
等待阻塞:运行状态下(Running)的线程执行o.wait()方法,JVM会把该线程放入等待队列中(waitting queue)
-
同步阻塞:运行状态下(Running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中
-
其他阻塞:运行状态下(Running)的线程执行Thread.sleep()或t.join()方法,或者发出了I/O请求时,,JVM会把该线程置为阻塞状态。当sleep()状态超时,join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态
6|5线程状态之死亡状态Dead
线程死亡通常由以下三种方式执行:
-
正常结束:run()或call()方法执行完成,线程正常结束
-
异常结束:线程抛出一个未捕获的Exception或Error
-
调用stop:直接调用该线程的stop()方法,来结束该线程(但是该方法容易造成死锁,不推荐使用)
__EOF__

本文链接:https://www.cnblogs.com/destiny-2015/p/17190434.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)