java多线程-创建线程

大纲:

  1. Thread创建线程。
  2. Runnable接口。
  3. Callable接口。
  4. 小结

一、java创建线程--继承Thead类

创建一个类继承Thead类,并重写run方法。

class Test {
    public static void main(String[] args) {
        System.out.println("当前线程:"+Thread.currentThread());
        new TestThread().start();
        new TestThread().start();
    }

    static class TestThread extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程:"+Thread.currentThread());
        }
    }
}

/**
运行结果: 当前线程:Thread[main,5,main] 当前线程:Thread[Thread-0,5,main] 当前线程:Thread[Thread-1,5,main] */

二、java创建线程--实现Runnable接口

创建一个类实现Runnable接口,并重写run方法。

class Test {
    public static void main(String[] args) {
        System.out.println("当前线程:"+Thread.currentThread());
        new Thread(new TestThread()).start();
        new Thread(new TestThread()).start();
    }

    static class TestThread implements Runnable {
        @Override
        public void run() {
            System.out.println("当前线程:"+Thread.currentThread());
        }
    }
}

/**
运行结果:
 当前线程:Thread[main,5,main]
 当前线程:Thread[Thread-0,5,main]
 当前线程:Thread[Thread-1,5,main]
 */

三、java创建线程--实现Callable接口

Callable接口中只有一个call方法,任务写在call方法中,与Runnable不同的是,任务执行完成后Callable返回执行结果,也可以抛出任务执行时的异常。

public interface Callable<V> {
    V call() throws Exception;
}

Futrue接口共5个方法

  1. cancel取消任务,参数表示是否中断正在执行的任务。(1)任务没有开始或正在执行,返回true 。(2)任务执行完成,返回false。
  2. isCancelled:任务非正常执行完成,执行了cancel方法返回true。
  3. isDone:任务正常执行完成或任务执行了cancel都返回true。
  4. get:方法阻塞至任务执行完毕,返回执行结果,当任务执行报错时可以通过任务中抛出的ExecutionException拿到异常信息。
  5. 带参get:可以设置超时时间,任务执行超时,抛出TImeoutException。
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;
}

RunnableFuture接口实现了Runnable和Future接口

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

RunnableFuture接口有一个实现类FutureTask,FutureTask的构造函数接收一个Callable任务,又继承了Future接口,因此执行FutureTask任务可以拿到执行结果。

public class TestCallable {

    public static void main(String[] args) {
        System.out.println("start");
        //执行任务
        FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(1000);
                return "success";
            }
        });
        new Thread(task).start();

        //接收线程运算后的结果
        try {
            long start = System.currentTimeMillis();
            System.out.println("任务执行结果:" + task.get());//get为阻塞方法,阻塞至任务执行结束
            long end = System.currentTimeMillis();
            long process = end - start;
            System.out.println("任务执行了:" + process + "毫秒");
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("end");
    }
}

/**
 运行结果:
   start
   任务执行结果:success
   任务执行了:1018毫秒
   end
 */

小结:

  1. Thread类中start方法首先为线程的执行准备好系统资源,然后再去调用run方法,因此run方法不需要我们手动调用。
  2. Thread和Runnable方式执行任务都无法在主线程中获取任务的执行结果,Callable执行任务可以获取执行结果,执行结果通过Future的get方法获取。
  3. Thread和Runnable方式执行任务都无法在主线程中获取任务执行的异常信息,Callable执行任务可以通过Future中的get方法抛出异常。
  4. 这些执行的任务的线程都是被主线程创建出来的子线程。
原文地址:https://www.cnblogs.com/liuboyuan/p/9945652.html