java线程的三种创建方式详细分析(全)

前言

关于线程这部分内容讲的比较多,可看我之前的文章

  1. 【操作系统】线程与进程的深入剖析(全)
  2. 【操作系统】守护线程和守护进程的区别

对于线程Thread的分析 也可看我之前的文章

  1. java之Thread类详细分析(全)
  2. java之Thread类实战模板(全)
  3. 多线程中run()和start()的异同详细分析(全)

对于创建方式的汇总以及方式 可看我这篇文章的总结对比

1. 继承Thread类

定义Thread类的子类,并重写该类的run方法

class MyThread extends Thread{  
      @Override
      public void run() {
       //要运行的代码
    }
}
new MyThread().start()  ;   

2. 实现Runnable 接口

class Mythread implements Runnable {
	 @Override
    public void run() {
        //方法 
    }

}

3. 通过Callable和Future创建线程

//实现Callable接口
class MyThread2 implements Callable {

    @Override
    public Integer call() throws Exception {
        return 200;
    }
}
  • 不可以像下面这么创建

不可以new Thread(new MyThread2(),"BB").start();
因为Thread的构造函数中没有Callable接口的参数设置

FutureTask的构造方法有

  • FutureTask(Callable<> callable) 创建一个FutureTask,一旦运行就执行给定的Callable
  • FutureTask(Runnable runnable,V result)创建一个FutureTask,一旦运行就执行给定的Ru你那边了,并安排成功完成时get返回给定的结果

其他常用的代码:
get()获取结果
isDone()判断是否计算结束

FutureTask 具体实现方法可以有两种方式(此处用的泛型参数)
第一种是

//实现Callable接口
class MyThread2 implements Callable {

    @Override
    public Integer call() throws Exception {
        return 200;
    }
}

FutureTask<Integer> futureTask1 = new FutureTask<>(new MyThread2());

第二种是

//lam表达式
FutureTask<Integer> futureTask2 = new FutureTask<>(()->{
    System.out.println(Thread.currentThread().getName()+" come in callable");
    return 1024;
});

创建线程new Thread(futureTask2,"lucy").start();
获取结果System.out.println(futureTask2.get());

所谓的FutureTask是在不影响主任务的同时,开启单线程完成某个特别的任务,之后主线程续上单线程的结果即可(该单线程汇总给主线程只需要一次即可)
如果之后主线程在开启该单线程,可以直接获得结果,因为之前已经执行过一次了

具体完整代码案例

//比较两个接口
//实现Runnable接口
class MyThread1 implements Runnable {
    @Override
    public void run() {

    }
}

//实现Callable接口
class MyThread2 implements Callable {

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName()+" come in callable");
        return 200;
    }
}

public class Demo1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //Runnable接口创建线程
        new Thread(new MyThread1(),"AA").start();

        //Callable接口,报错
       // new Thread(new MyThread2(),"BB").start();

        //FutureTask
        FutureTask<Integer> futureTask1 = new FutureTask<>(new MyThread2());

        //lam表达式
        FutureTask<Integer> futureTask2 = new FutureTask<>(()->{
            System.out.println(Thread.currentThread().getName()+" come in callable");
            return 1024;
        });

        //创建一个线程
        new Thread(futureTask2,"lucy").start();
        new Thread(futureTask1,"mary").start();

//        while(!futureTask2.isDone()) {
//            System.out.println("wait.....");
//        }
        //调用FutureTask的get方法
        System.out.println(futureTask2.get());

        System.out.println(futureTask1.get());

        System.out.println(Thread.currentThread().getName()+" come over");
       }
}

代码截图
在这里插入图片描述

4. 总结

比较Runnable接口和Callable接口

  • Callable中的call()计算结果,如果无法计算结果,会抛出异常
  • Runnable中的run()使用实现接口Runnable的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用该对象的run方法
  • 总的来说:run()没有返回值,不会抛出异常。而call()有返回值,会抛出异常

Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值