Java面试题8——创建线程的三个方法

创建线程的三个方法

1.继承thread类创建线程类

  • 第一步:定义thread类的子类,并重写该类的run方法,run方法的方法体就代表了线程需要完成的任务
  • 第二步:创建thread类的子类的实例,即创建了线程对象
  • 第三步:调用线程对象的start方法来启动该线程

以下为第一种创建方式的代码示例及其部分运行结果

//定义继承Thread类的子类
public class TThread extends Thread {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + "" + i);
            if (i == 20) {
            //实例化线程对象,并调用线程对象的start方法
                new TThread().start();
                new TThread().start();
            }
        }
    }
    int i = 0;
    //重写父类的run方法,里面是线程的需要完成的任务代码
    public void run() {
        for (; i < 100; i++) {
            System.out.println(getName() + "" + i);
        }
    }
}
main10//主线程运行
main11
main12
main13
main14
main15
main16
main17
main18
main19
main20
Thread-00//创建了名为Thread-0的子线程
Thread-01
Thread-02
Thread-03
Thread-04
Thread-10//创建了名为Thread-1的子线程,所以共创建了2个线程执行run方法
Thread-11
Thread-12

2.通过runable接口创建线程类

  • 定义runable接口的实现类,并重写该类的run方法,该run方法的方法体同样是该线程的执行体
  • 创建该实现类的实例,并将该实例作为thread的参数来创建Thread对象。该对象才是真正的线程对象
  • 调用线程对象的start方法来启动线程。

以下为第二种创建方式的代码示例及其部分运行结果

//创建了Runable接口的实例RThread
public class RThread implements Runnable {
    public static void main(String[] args) {
        for(int i = 0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+""+i);
            if (i == 20){
            //实例化RThread类
                RThread rt = new RThread();
                //实例化Thread类并把Runable接口的实例对象传入,共创建了两个线程对象。
                new Thread(rt,"新线程1").start();
                new Thread(rt,"新线程2").start();
            }
        }
    }
    private int i;
    //重写了run方法
    public void run(){
        for(int i = 0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+""+i);
        }
    }
}
main12//主线程运行
main13
main14
main15
main16
main17
main18
main19
main20
新线程10//创建子线程1
main21
新线程20
新线程11
新线程21//创建子线程2

3.通过callable接口创建线程类

  • 定义callable接口的实现类,并实现call方法,该call方法将作为线程执行体,并且有返回值
  • 创建callable的实例,使用FutureTask类来包装callable对象,该类对象封装了该callable对象的方法的返回值
  • 使用FutureTask对象作为thread对象的target创建并启动新线程
  • 调用FutureTask对象的get方法来获得子线程结束后的返回值。

以下为第三种创建方式的代码示例及其部分运行结果

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
//创建了Callable接口的实例CThread
public class CThread implements Callable<Integer> {
    public static void main(String[] args)  throws Exception{
    //实例化实现了Runable接口的CThread类
        CThread ctt = new CThread();t
        //使用FutureTask类包装实例化对象ctt,该对象封装了call方法的返回值,通过get()可以随时取出子线程执行结果
        FutureTask<Integer> ft = new FutureTask<>(ctt);
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"的循环变量i的值"+i);
            if(i == 20){
                new Thread(ft,"有返回值的线程").start();
            }
        }
        try {
            System.out.println("子线程的返回值"+ft.get());
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
    //重写call方法
    @Override
    public Integer call() throws Exception {
        int i=0;
        for(;i<100;){
            i++;
          System.out.println(Thread.currentThread().getName()+""+i);
        }
        return i;
    }
}
main的循环变量i的值19
main的循环变量i的值20
main的循环变量i的值21
main的循环变量i的值22
main的循环变量i的值23
main的循环变量i的值24
main的循环变量i的值25
有返回值的线程1
main的循环变量i的值26
有返回值的线程2
-
-
-
有返回值的线程99
有返回值的线程100
子线程的返回值100//执行完主线程的的for循环,执行最后的try语句。

4.创建方法的比较
1、继承Thread类(不推荐):只能被单继承,不推荐使用

2、实现Runable的接口(推荐):不需要返回值时,推荐使用

3、实现Callable接口(JDK1.5): 核心方法叫call()方法(相当于run()),有返回值,推荐使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值