多线程的三种创建方式详讲 以及具体使用方法和区别(Thread Runnable Callable)

多线程第一种创建方式

继承Thread类

package CreatThread;

/**
 * Description:创建多线程类的第一种方式,  继承Thread类
 *             Thread是一个类,它实现了Runable接口
 * 使用方式:ThreadDemo threadDemo = new ThreadDemo();
 *         threadDemo.start();
 *         直接创建一个对象,因为它继承了Thread类,所以它就是一个线程.直接调用start方法.
 * @Author Fann
 * @Data 2019/2/1
 */
public class ThreadDemo extends Thread{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"   ExtendsThread");
    }
}

多线程第二种创建方式

实现Runnable接口

package CreatThread;

/**
 * Description:创建多线程类的第二种方式 实现Runnable接口
 *              Runnable是一个接口,需要用implements
 * 使用方式:RunnableDemo runnableDemo = new RunnableDemo();
 *         Thread thread = new Thread( runnableDemo );
 *         thread.start();
 *         先创建一个类,它是Runnable类型的,需要加入到一个Thread中,然后就成为了一个线程,就可以调用线程的start方法.
 * @Author Fann
 * @Data 2019/2/1
 */
public class RunnableDemo implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"   RunnableDemo");
    }
}

多线程第三种创建方式

实现Callable接口

package CreatThread;

import java.util.concurrent.Callable;

/**
 * Description:多线程类的第三种创建方式: 实现Callable接口
 *             需要重写call方法.这个方法会抛出异常,会有返回值.
 * 使用方式: ExecutorService exec = Executors.newSingleThreadExecutor();
 *         CallableDemo callableDemo = new CallableDemo();
 *         Future<Integer> future = exec.submit( callableDemo );
 *
 * @Author Fann
 * @Data 2019/2/1
 */
public class CallableDemo implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("   CallableDemo");
        return 1000;
    }
}

三种方式进行演示:

package CreatThread;
import java.util.concurrent.*;

/**
 * Description:
 *
 * @Author Fann
 * @Data 2019/2/1
 */
public class Main {
    public static void main(String[] args) {
        System.out.println("Main");

        //第一种,继承Thread类
        ThreadDemo threadDemo = new ThreadDemo();
        threadDemo.start();

        //第二种,实现Runnable接口
        RunnableDemo runnableDemo = new RunnableDemo();
        Thread thread = new Thread( runnableDemo );
        thread.start();

        //第三种,实现Callable接口
        ExecutorService exec = Executors.newSingleThreadExecutor();
        CallableDemo callableDemo = new CallableDemo();
        Future<Integer> future = exec.submit( callableDemo );
        try {
            Integer integer = future.get();
            future.cancel( false );
            System.out.println(integer);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

PS:run和start的区别:
start() 是启动一个新线程,只可以被调用一次
run() 新线程启动之后会自动调用run方法,可以重复调用

package CreatThread;
import java.util.concurrent.*;

/**
 * Description:
 *
 * @Author Fann
 * @Data 2019/2/1
 */
public class Main {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName()+" MainRunning");
        RunnableDemo runnableDemo = new RunnableDemo();
        Thread subThread = new Thread( runnableDemo,"subThread" );
        subThread.run(); //在这里调用run 是在主线程种调用run,没有达到多线程的效果
        subThread.start();//调用start后是重新启动了一个新线程,它会自己调用run方法
    }
}
main MainRunning
main   RunnableDemo
subThread   RunnableDemo

三种创建方式的区别:

三种创建方式的区别:
1.继承Thread类为单继承,不能继承其它类,而实现Runnable接口的类可以继承其他类(多实现).
所以实现Runnable接口更加灵活.
2.通过实现Runnable接口的方式可以实现多线程内的资源共享
3.实现Runnable接口线程类的多个线程,可以更方便的访问同一个遍历,而Thread类需要进行内部类替换.
4.线程池只能存放Runnable或者Callable类的线程,不能直接放入继承Thread类的线程
5.Callable规定的方法是call() 而Runnable规定的方法是run()
Callable的任务执行完毕后可以返回值,而Runnable的任务是不能返回值的.
call()方法可以抛出异常,而run()方法不行.
6.运行Callable任务可以得到一个Future对象,Future表示异步计算的结果
它提供检查计算是否完成的方法,以等到计算的完成,并检索计算的结果.
通过Future对象可了解任务的执行情况,可取消任务的执行,还可以获取任务执行的结果.
Executors是线程池的工具类
子线程的结果可以返回给主线程,并且子线程的执行可以被取消

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值