线程创建的三种方法:继承Thread类,实现Runnable接口,实现Callable接口
2021/7/19 23:05:22
本文主要是介绍线程创建的三种方法:继承Thread类,实现Runnable接口,实现Callable接口,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
线程创建
三种创建方式
1. 继承Thread类
- 自定义线程类继承Thread类
- 重写run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动线程
线程不一定执行,CPU按排调度
package multithreading; // 创建线程方式一:继承Thread类,重写run()方法,调用start()开启线程 // 总结:注意,线程开启不一定立即执行,由CPU调度安排 public class TestThread1 extends Thread { @Override public void run() { // run方法线程体 for (int i = 0; i < 20; i++) { System.out.println("我在看代码---"+i); } } public static void main(String[] args) { // main线程,主线程 // 创建一个线程对象 TestThread1 testThread1 = new TestThread1(); // 调用start()方法开启线程 testThread1.start(); for (int i = 0; i < 2000; i++) { System.out.println("我在学习多线程---"+i); } } }
调用start()先执行主线程中内容
调用run()主线程先执行run方法中内容
2. 实现Runnable接口
package multithreading; // 创建线程方法2:实现Runnable接口,重写run()方法,执行线程需要丢入Runnable接口的实现类 public class TestThread3 implements Runnable{ @Override public void run() { // run方法线程体 for (int i = 0; i < 200; i++) { System.out.println("我在看代码---"+i); } } public static void main(String[] args) { // 创建runnable接口的实现类对象 TestThread3 testThread3 = new TestThread3(); // 创建线程对象,通过线程对象来开启线程,代理 Thread thread = new Thread(testThread3); thread.start(); // new Thread(testThread3).start(); for (int i = 0; i < 2000; i++) { System.out.println("我在学习多线程---"+i); } } }
Thread && Runnable
-
继承Thread类
- 子类继承Thread类具备多线程能力
- 启动线程:子类对象.start()
- 不建议使用:避免OOP单继承局限性
-
实现Runnable接口
- 实现接口Runnable具有多线程能力
- 启动线程:传入目标对象+Thread对象.start()
- 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
3. 实现Callable接口(了解)
-
实现Callable接口,需要返回值
-
重写call方法,需要抛出异常
-
创建目标对象
-
创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(3);
-
提交执行:Future
result1 = ser.submit(t1); -
获取结果:boolean rs1 = result1.get();
-
关闭服务:ser.shutdownNow();
演示:利用Callable改造图片下载案例
package multithreading; import java.util.concurrent.*; // 创建线程方式三:实现Callable接口 // 使用Callable的好处:1.可以定义返回值 2.抛出异常 public class TestCallable implements Callable<Boolean> { private String url; // 网络图片地址 private String name; // 保存的文件名 public TestCallable(String url,String name){ this.url = url; this.name = name; } // 下载图片线程的执行体 @Override public Boolean call() throws Exception { WebDownLoader webDownLoader = new WebDownLoader(); webDownLoader.downloader(url,name); System.out.println("下载了文件名为:"+name); return true; } public static void main(String[] args) throws ExecutionException,InterruptedException { // 抛出异常 TestCallable t1 = new TestCallable("https://img-pre.ivsky.com/img/tupian/pre/202012/23/youshan_yingguo_lanse_duanmaomao-003.jpg","cat1.jpg"); TestCallable t2 = new TestCallable("https://img-pre.ivsky.com/img/tupian/pre/202012/23/youshan_yingguo_lanse_duanmaomao-002.jpg","cat2.jpg"); TestCallable t3 = new TestCallable("https://img-pre.ivsky.com/img/tupian/pre/202012/23/youshan_yingguo_lanse_duanmaomao-005.jpg","cat3.jpg"); // 创建执行服务,线程池: ExecutorService ser = Executors.newFixedThreadPool(3); // 提交执行: Future<Boolean> r1 = ser.submit(t1); Future<Boolean> r2 = ser.submit(t2); Future<Boolean> r3 = ser.submit(t3); // 获取结果: boolean rs1 = r1.get(); boolean rs2 = r2.get(); boolean rs3 = r3.get(); System.out.println(rs1); // 打印返回值 System.out.println(rs2); System.out.println(rs3); // 关闭服务: ser.shutdownNow(); } }
执行结果:
这篇关于线程创建的三种方法:继承Thread类,实现Runnable接口,实现Callable接口的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-22怎么通过控制台去看我的页面渲染的内容在哪个文件中呢-icode9专业技术文章分享
- 2024-12-22el-tabs 组件只被引用了一次,但有时会渲染两次是什么原因?-icode9专业技术文章分享
- 2024-12-22wordpress有哪些好的安全插件?-icode9专业技术文章分享
- 2024-12-22wordpress如何查看系统有哪些cron任务?-icode9专业技术文章分享
- 2024-12-21Svg Sprite Icon教程:轻松入门与应用指南
- 2024-12-20Excel数据导出实战:新手必学的简单教程
- 2024-12-20RBAC的权限实战:新手入门教程
- 2024-12-20Svg Sprite Icon实战:从入门到上手的全面指南
- 2024-12-20LCD1602显示模块详解
- 2024-12-20利用Gemini构建处理各种PDF文档的Document AI管道