创建线程的三种方式

来源:互联网 发布: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