创建线程的三种方式
来源:互联网 发布:unity3d ui弹出动画 编辑:程序博客网 时间:2024/06/01 08:57
线程的创建一共有三种方式:
1. 继承于Thread类,重写run()方法;
2. 实现Runable接口,实现里面的run()方法;
3. 使用ExecutorService、Callable、Future实现有返回结果的多线程。Callable是一个接口,有一个有返回值的run()方法。前面两种,run()方法是没有返回值的。
在详细了解这三种方法之前,先来理解一下为什么线程要这样创建:形象点来说,Thread是一个工人,run()方法里面的便是他的任务栏,这个任务栏默认是空的。当你想要这个线程做点什么时,你可以重写Thread里面的run方法,重写这个工人的任务栏;也可以通过runable、callable接口,从外部赋予这个工人任务。
一、3种方式的详细介绍
1、继承于Thread类,重写run()方法
Thread thread = new MyThread(); //线程启动thread.start();
MyThread 类
//继承Threadclass MyThread extends Thread{ //重写run方法 @Override public void run() { //任务内容.... System.out.println("当前线程是:"+Thread.currentThread().getName()); }}
运行结果:
当前线程是:Thread-0
如果线程类使用的很少,那么可以使用匿名内部类,请看下面的例子:
Thread thread = new Thread(){ @Override public void run() { //任务内容.... System.out.println("当前线程是:"+Thread.currentThread().getName()); } };
2、实现Runable接口,实现里面的run()方法:
第一种方法- -继承Thread类的方法,一般情况下是不建议用的,因为java是单继承结构,一旦继承了Thread类,就无法继承其他类了。所以建议使用 实现Runable接口 的方法;
Thread thread = new Thread(new MyTask()); //线程启动thread.start();
MyTask 类:
//实现Runnable接口class MyTask implements Runnable{ //重写run方法 public void run() { //任务内容.... System.out.println("当前线程是:"+Thread.currentThread().getName()); }}
同样,如果这个任务类(MyTask )用的很少,也可以使用匿名内部类:
Thread thread = new Thread(new Runnable() { @Override public void run() { //任务内容.... System.out.println("当前线程是:"+Thread.currentThread().getName()); } });
3、使用ExecutorService、Callable、Future实现有返回结果的多线程。
这个后续补充。
二、关于run()方法的思考
看看下面这种情况:线程类Thread 接收了外部任务,同时又用匿名内部类的方式重写了内部的run()方法,这样岂不是有两个任务,那么究竟会执行那个任务呢?还是两个任务一起执行呢?
Thread thread = new Thread(new MyTask()){ @Override public void run() {//重写Thread类的run方法 System.out.println("Thread 类的run方法"); } }; //线程启动 thread.start();
//实现Runnable接口class MyTask implements Runnable{ //重写run方法 @Override public void run() { //任务内容.... System.out.println("这是Runnable的run方法"); }}
运行结果:
Thread 类的run方法
通过上面的结果,可以看出:线程最后执行的是Thread类内部的run()方法,这是为什么呢?我们先来分析一下JDK的Thread源码:
private Runnable target;
public void run() { if (target != null) { target.run(); } }
一切都清晰明了了,Thread类的run方法在没有重写的情况下,是判断一下是否有Runnable 对象传进来,如果有,那么就调用Runnable 对象里的run方法;否则,就什么都不干,线程结束。所以,针对上面的例子,一旦你继承重写了Thread类的run()方法,而你又想可以接收Runable类的对象,那么就要加上super.run(),执行没有重写时的run方法,改造的例子如下:
Thread thread = new Thread(new MyTask()){ @Override public void run() {//重写Thread类的run方法 //调用父类Thread的run方法,即没有重写时的run方法 super.run(); System.out.println("Thread 类的run方法"); } };
运行结果:
这是Runnable的run方法
Thread 类的run方法
参考文献:
http://blog.csdn.net/aboy123/article/details/38307539
- java创建线程的三种方式
- iOS创建线程的三种方式
- iOS创建线程的三种方式
- 创建线程的三种方式浅析
- java创建线程的三种方式
- 多线程-创建线程的三种方式
- 创建线程的三种方式
- 创建线程的三种方式
- NSThread创建线程的三种方式
- Java创建线程的三种方式
- Java线程创建的三种方式
- 创建线程对象的三种方式
- 创建线程的三种方式对比
- 【多线程】创建线程的三种方式
- Java创建线程的三种方式
- Java创建线程的三种方式
- 创建线程的三种方式
- 创建线程的三种方式
- codeforces 776C Molly's Chemicals(连续子序列和为k的次方的个数)
- html
- js各种排序
- linux每天一命令:ls
- JS字符串转换数字
- 创建线程的三种方式
- 多态的实现和原理
- 小猪的C语言快速入门系列(九)
- Spring AOP 使用
- DevOps 在公司项目中的实践落地
- php-webdriver selenium 打开火狐浏览器的https网址报错
- oracle 导入导出
- 等式转换降低时间复杂度
- hbase 1.2.6 无法通过web访问hbase 节点查看RegionServer信息