实现线程的方式(继承Thread类,实现Runnable和Callable接口)(小白教程含泪总结,读完必会!!!!)

  1. 创建线程

 在Java中使用Thread类表示线程,每一个线程都是Thread类的对象或者子类的对象,相当于Thread类是所有线程的父类,所有的线程对象都是一个任务,需要调度器安排序列被CPU执行,在使用了Thread类时,这些线程对象会被同时执行;

 实现创建线程的方式:继承Thread类、实现Runnable接口、实现Callable接口、使用线程池。

1.1  继承Thread类

  1. 多线程的启动方式:
  • 自定义线程类继承Thread类;
  • 重写run()方法;
  • 创建线程对象并使用调用start()方法开启线程;

        2.   在使用过程中run()方法只是重写,不需要调用,start()就是调用run()方法;

        3.   Thread类常用方法:

  • run()方法:
  • Run方法在执行时必须要重写,返回值为void类型;
  • start()方法:
  • 启动线程,执行run()方法中内容,返回类型为void类型;
  • currentThread()方法:
  • 返回当前线程,返回类型为Thread类型,一般调用该方法后还需调用其他方法结合使用,例:thread.currentThread().getName();该语句时返回当前对象thread的线程中的线程名称;
  • getName()方法:
  • 获取该线程的名称,返回类型为String类型;
  • setName()方法:
  • 设置线程名称,返回类型为void类型;
  • sleep()方法:
  • 该sleep(long millis)为使当前线程睡眠阻塞,睡眠阻塞时间millis类型为long类型,单位是毫秒;
  • 在睡眠过程中不占用cpu,空余线程分配给其他线程使用cpu,当前线程睡眠后重新到调度器中排队执行;
  • 注意:
  • 在springboot框架中使用sleep()方法时,需有抛出异常处理,一般对其使用InterruptedException抛出异常,使用try-catch语句处理抛出异常语句;但在springboot中使用注解@SnackThrows即可
  • 每个对象都有一个锁,sleep不会释放锁;
  • join()方法:
  • join合并线程,待此线程执行完毕后再执行其他线程,其他线程阻塞(即插队执行该线程);
  • 在当线程a中的调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完毕,线程才结束阻塞,继续执行。
  • 例:线程a的运行过程中需要一个参数,这个参数需要线程b提供,这时,就需要join()方法;
  • 在springboot框架中使用join()方法时,需有抛出异常处理,一般对其使用InterruptedException抛出异常,使用try-catch语句处理抛出异常语句;但在springboot中使用注解@SnackThrows即可
  • isAlive()方法:
  • 判断线程是否还活着,返回类型是boolean类型;
  • setPriority()和getPriority()方法:
  • 设置线程的优先级和获取线程优先级;返回类型为int类型;1-10表示优先级,优先级越高数字越大,不设置优先级自动默认优先级为5;
  • 注意:优先级越大抢占CPU概率越大,优先级越大不一定CPU先执行该线程;
  • 例:已有一个线程Thread对象thread,thread.setPriority(1)、thread.getPriority()

        setDaemon()方法:

  • 设置守护线程,当其他非守护线程执行完毕后守护线程陆续结束;thread.setDaemon(false);这个方法默认为false,当为false情况下,外面主线程运行结束,停了,开启的子线程依然在跑。thread.setDaemon(true);当为守护线程的时候,外面主方法结束,主方法开启的子线程守护线程就会结束。
  • 例:把Thread类对象thread1设置为守护线程,thread.setDaemon(true)

          yield()方法:

  • 礼让线程,让当正在执行的线程暂停,但不阻塞,礼让后线程重新回到初始状态,多个线程同时竞争CPU,礼让不一定成功;
  • 需要用类Thread.yield()方法启用;

1.2实现Runnable()接口(重点)

  1.   多线程启动方法:
  • 自定义一个类实现Runnable接口;
  • 重写run()方法;
  • 创建线程对象,调用start()方法启动线程;

    2.   方法:(和继承Thread方法类似)

   3.  优化代码:

例:

使用RunnableDemo类实现Runnable接口;

RunnableDemo runableDemo = new RunnableDemo();

Thread thread = new Thread(RunnableDemo);

thread.setName(“aaa”);

thread.start();

优化后:

RunnableDemo runnabledemo = new RunnableDemo();

new Thread(runnableDemo , “aaa”).start();

注意:

实现Runnable接口与继承Thread类的异同在于:

  • 不同点:实现Runable接口方式实现它的类可能还继承了其他父类,在Java中只能有一个继承父类,若再继承Thread类则冲突,故再使用过程中建议使用实现Runnable接口使用多线程;
  • 相同点:都需要重写run()方法;


  1. Runnable接口的优点: 

避免单继承的局限,灵活方便,方便同一个对象被多个线程使用;

1.3实现Callable()接口

  • 多线程启动方法:
  • 自定义一个类实现Callable接口;
  • 重写call()方法;
  • 创建线程对象;

方法一:

  • 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
  • 此处newFixedThreadPool(1)的“1”表示有一个线程;
  • 执执行提交:Future<T> result1 = ser.submit(t1);
  • 获取结果:boolean r1 = result1.get();
  • 关闭服务:ser.shutdownNow();

方法二:

  1.         创建FutureTask对象:FutureTask<T> futureTask = new FutureTask<>(线程对象);
  2.         创建Thread对象:Thread thread = new Thread(futureTask);
  3.         开启线程:thread.start();

        对比:

Callable接口可以实现多线程运行的结果,返回一个boolean类型

注意:

在自定义类继承implements Callable接口时,需要注意后必须跟一个泛型类,该泛型类的类型可以自定义,pubic class MyCallable implements Callable<T>

例:pubic class MyCallable implements Callable<Integer>{

该泛型类在使用过程中决定了call()方法的返回类型;

@Override

Public Integer call(){

1.4 三种方法优缺点:

方法

优点

缺点

继承Thread类

可以直接使用Thread类中方法;

不可继承其他类,可实现的扩展性差

实现Runnable接口

可继承其他类,实现接口功能

不能直接使用Thread类中的方法,没有返回值;

实现Callable接口

可继承其他类,实现接口功能;有返回值且返回类型可自定义;

不能直接使用Thread类中的方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值