Java简单创建线程的三种方式

  • 一 、继承Thread类创建

  1. 通过继承Thread类,重写其run方法,run()为线程要执行的任务,因此又称为执行体。
  2. 创建Thread的子类的实例,创建线程对象,调用start()方法启动线程

线程类已经继承Thread类,则无法继承其他类;每个线程都需要创建不同的Thread类,多个线程间无法共享线程类的实例变量

public class HelloWorldThread extends Thread{

    @Override
    public void run() {
        System.out.println("Hello world!");
    }

    public static void main(String[] args) {
        Thread thread = new HelloWorldThread();
        thread.start();
    }
}
  • 二、通过实现Runnable接口创建

  1. 创建Runnable接口的实现类,重写该接口的run()方法
  2. 创建Thread对象,同时创建实现类的实例作为Thread的target,调用start()方法启动线程

(Thread对象是真正的线程,实现类只是线程的执行体)

public class HelloWorldThread implements Runnable{

    @Override
    public void run() {
        System.out.println("Hello world!");
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new HelloWorldThread());
        thread.start();
    }
}
  • 三、通过Callable和Future创建线程

继承Thread类和实现Runnable的方式没有返回值,也无法抛出异常,如何判断线程是否执行完成,了解任务执行情况,取消任务的执行,这就需要Callable和Future来创建线程

  1. 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
  2. 使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
  3. 使用FutureTask对象作为Thread对象的target创建并启动新线程。
  4. 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。

Callable类似于Runnable接口的增强版,其提供的call()方法将作为线程的执行体,同时允许有返回值。但是Thread类的target参数是Runnable类型。

 public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

这时就需要借助 Future接口,此接口可以接受call() 的返回值,RunnableFuture接口是Future接口和Runnable接口的子接口,可以作为Thread对象的target ,并且, Future 接口提供了一个实现类:FutureTask 。

public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}

FutureTask实现了RunnableFuture接口,可以作为 Thread对象的target。

public class CallableTest implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        Random random = new Random();
        Integer add = 0;
        for (int i = 0; i < 100; i++) {
            add = add + i;
        }
        System.out.println("CallableTest:" + add);
        return add;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<>(new CallableTest());
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get());
    }
}

FutureTask是一个包装器,使用FutureTask类来包装Callable对象,它通过接受Callable来创建,调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。

最后我们来分析下Future接口

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
  1. cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
  2. isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
  3. isDone方法表示任务是否已经完成,若任务完成,则返回true。
  4. get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回。
  5. get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值