大纲:
- Thread创建线程。
- Runnable接口。
- Callable接口。
- 小结
一、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个方法
- cancel取消任务,参数表示是否中断正在执行的任务。(1)任务没有开始或正在执行,返回true 。(2)任务执行完成,返回false。
- isCancelled:任务非正常执行完成,执行了cancel方法返回true。
- isDone:任务正常执行完成或任务执行了cancel都返回true。
- get:方法阻塞至任务执行完毕,返回执行结果,当任务执行报错时可以通过任务中抛出的ExecutionException拿到异常信息。
- 带参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 */
小结:
- Thread类中start方法首先为线程的执行准备好系统资源,然后再去调用run方法,因此run方法不需要我们手动调用。
- Thread和Runnable方式执行任务都无法在主线程中获取任务的执行结果,Callable执行任务可以获取执行结果,执行结果通过Future的get方法获取。
- Thread和Runnable方式执行任务都无法在主线程中获取任务执行的异常信息,Callable执行任务可以通过Future中的get方法抛出异常。
- 这些执行的任务的线程都是被主线程创建出来的子线程。