Java多线程3种实现方式

1、继承Thread类

package demo;

public class FirstThread extends Thread{
    private String name; // 定义name属性
    public FirstThread(String name) {
        this.name = name;
    }
    public void run() {// 重写
        for (int i = 0; i < 10; i++) {
            System.out.println(name+i);
        }
    }
    public static void main(String[] args) {
        FirstThread t1 = new FirstThread("线程A") ;
        FirstThread t2 = new FirstThread("线程B") ;
        t1.start(); // 调用线程体
        t2.start() ;// 调用线程体
        for(int i=0;i<10;i++){
            System.out.println("主线程"+i);
        }

    }

}

运行结果如下。由于循环次数较少,可能从运行结果可不到多线程并发运行的消息,多执行几次即可看到类似下面的结果。

主线程0
线程B0
线程A0
线程B1
主线程1
线程B2
线程B3
线程A1
线程B4
线程B5
线程B6
线程B7
线程B8
线程B9
主线程2
线程A2
线程A3
线程A4
线程A5
线程A6
线程A7
线程A8
线程A9
主线程3
主线程4
主线程5
主线程6
主线程7
主线程8
主线程9

这里写图片描述

2、实现Runnable接口

package demo;

public class SecondThread implements Runnable{
    private String name; // 定义name属性
    public SecondThread(String name) {
        this.name = name;
    }
    public void run() {// 重写
        for (int i = 0; i < 10; i++) {
            System.out.println(name+i);
        }
    }
    public static void main(String[] args) {
        new Thread(new SecondThread("张三")).start();
        new Thread(new SecondThread("李四")).start();
        for(int i=0;i<10;i++){
            System.out.println("主线程"+i);
        }
    }

}
主线程0
主线程1
主线程2
主线程3
主线程4
张三0
张三1
张三2
张三3
张三4
张三5
张三6
张三7
张三8
张三9
李四0
李四1
李四2
李四3
李四4
李四5
李四6
李四7
李四8
李四9
主线程5
主线程6
主线程7
主线程8
主线程9

这里写图片描述

3、Callable+Future实现

从 Java 5 开始,Java 提供了 Callable 接口,该接口是runnable 的增强版,Callable 提供类一个 call() 方法可以作为线程执行体,但是call() 方法的功能更强大。请记住call()方法的特征:

  • call() 方法可以有返回值
  • call() 方法可以声明抛出异常

由于Java多线程最后都要通过Thread对象的start方法启动,我们已经知道可以将Runnable对象直接作为Thread的target参数来构造线程。然而Callable 接口和Runnable接口没有直接关系,或者说Callable 接口不是Runnable接口的子接口,所以Callable对象不能直接作为Thread的target。

Java5提供了FutureTask类实现了Future接口和Runnable接口,因此FutureTask对象可以作为Thread的target。
此外,Future接口的方法可以同来控制与之关联的Callable任务。
在Future接口中声明了5个方法:

  • cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false;
  • isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
  • isDone方法表示任务是否已经完成,若任务完成,则返回true;
  • get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
  • get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
package demo;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThirdThread implements Callable<Integer>{
    private int ticket = 10;
    @Override
    public Integer call(){
      for ( int i = 0;i<10;i++) {
        if(this.ticket>0){
          System.out.println(Thread.currentThread().getName() + ", ticket=" + ticket--);
        }
      }
      return ticket;
    }

    public static void main(String[] args){
        ThirdThread callable = new ThirdThread();
        FutureTask<Integer> task1 = new FutureTask<Integer>(callable);
        new Thread(task1,"Callable线程1").start();
        FutureTask<Integer> task2 = new FutureTask<Integer>(callable);
        new Thread(task2,"Callable线程2").start();
        try {
              System.out.println("Callable线程1的返回值="+task1.get());
              System.out.println("Callable线程2的返回值="+task2.get());
            } catch (InterruptedException e) {
              e.printStackTrace();
            } catch (ExecutionException e) {
              e.printStackTrace();
            }
    }
}

运行结果

Callable线程2, ticket=10
Callable线程2, ticket=9
Callable线程1, ticket=8
Callable线程2, ticket=7
Callable线程2, ticket=6
Callable线程2, ticket=5
Callable线程2, ticket=4
Callable线程2, ticket=3
Callable线程2, ticket=2
Callable线程2, ticket=1
Callable线程1的返回值=0
Callable线程2的返回值=0

这里写图片描述

说明:程序最后调用FutureTask 对象的get()方法来返回Call()方法的返回值,导致主线程被阻塞,直到call()方法结束并返回为止。

总结:创建有返回值的线程基本流程

  1. 创建Callable 接口的实现类,并实现线程执行体call()方法,该方法有返回值。然后再重建Callable实现类对象。从Java 8开始,可以通过Lambda表达式直接定义Callable对象。
  2. 通过Callable对象创建FutureTask对象;FutureTask对象封装了该Callable对象的call()方法的返回值。
  3. 通过FutureTask对象创建Thread对象并启动线程。
  4. 调用FutureTask对象的get()方法来获取子线程执行结束后的返回值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值