线程创建的三种方式及区别
创建方式
1.继承Thread类,子类重写run()方法,调用子类的strat()启动线程。
2.实现Runnable接口,实现run()方法,调用对象start()启动线程。
3.实现Callable接口,实现call()方法,用FutureTask()封装实现类。使用FutureTask对象作为Thread对象调用start()启动线程,调用FutureTask对象的get()方法获取返回值()。
三种方式的优缺点
1.采用继承Thread类方式:
(1)优点:编写简单。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
- 采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
- Runnable和Callable的区别:
(1)Callable规定的方法是call(),Runnable规定的方法是run()。
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得。
(3)call方法可以抛出异常,run方法不可以,因为run方法本身没有抛出异常,所以自定义的线程类在重写run的时候也无法抛出异常
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
示列代码图下
1.
package Thread; import java.util.concurrent.*; public class TestThread { public static void main(String[] args) throws Exception { testExtends(); } public static void testExtends() throws Exception { Thread t1 = new MyThreadExtends(); Thread t2 = new MyThreadExtends(); t1.start(); t2.start(); } } class MyThreadExtends extends Thread { @Override public void run() { System.out.println("通过继承Thread,线程号:" + currentThread().getName()); } }
2.
package Thread; import java.util.concurrent.*; //测试类 public class TestThread { public static void main(String[] args) throws Exception { testImplents(); } public static void testImplents() throws Exception { MyThreadImplements myThreadImplements = new MyThreadImplements(); Thread t1 = new Thread(myThreadImplements); Thread t2 = new Thread(myThreadImplements, "my thread -2"); t1.start(); t2.start(); } } //线程类 class MyThreadImplements implements Runnable { @Override public void run() { System.out.println("通过实现Runable,线程号:" + Thread.currentThread().getName()); } }
3.
package Thread; import java.util.concurrent.*; public class TestThread { public static void main(String[] args) throws Exception { testCallable(); } public static void testCallable() throws Exception { Callable callable = new MyThreadCallable(); FutureTask task = new FutureTask(callable); new Thread(task).start(); System.out.println(task.get()); Thread.sleep(10);//等待线程执行结束 //task.get() 获取call()的返回值。若调用时call()方法未返回,则阻塞线程等待返回值 //get的传入参数为等待时间,超时抛出超时异常;传入参数为空时,则不设超时,一直等待 System.out.println(task.get(100L, TimeUnit.MILLISECONDS)); } } class MyThreadCallable implements Callable { @Override public Object call() throws Exception { System.out.println("通过实现Callable,线程号:" + Thread.currentThread().getName()); return 10; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix