Java 提供了三种创建线程的方法
1.继承Thread接口
1 public class Thread2Thread { 2 public static void main(String[] args) { 3 new MyThread1().start(); 4 new Thread(new MyThread1(), "线程2").start(); 5 } 6 } 7 8 /** 9 * 通过继承Thread类 10 */ 11 class MyThread1 extends Thread { 12 /** 13 * 重写run方法 14 */ 15 @Override 16 public void run() { 17 // TODO Auto-generated method stub 18 super.run(); 19 } 20 }
2.实现Runnable接口
1 package com.testthread.demo4; 2 3 import java.util.concurrent.ExecutorService; 4 5 import static java.util.concurrent.Executors.*; 6 7 public class Thread2Runnable { 8 9 public static void main(String[] args) { 10 11 //case1:通过实现Runnable接口,来实现run方法的具体逻辑 12 new Thread(new MyThread2(), "线程1").start(); 13 //case2:匿名内部类 14 new Thread(new Runnable() { 15 @Override 16 public void run() { 17 // TODO Auto-generated method stub 18 19 } 20 }, "线程2").start(); 21 22 //其实case1和case2的本质是一样的 23 24 //case3:作为线程任务提交给线程池,通过线程池维护的工作者线程来执行。 25 ExecutorService executor = newCachedThreadPool(); 26 MyThread2 myThread2 = new MyThread2(); 27 executor.execute(myThread2); 28 executor.shutdown(); 29 } 30 } 31 32 /** 33 * 实现Runnable接口的线程类 34 */ 35 class MyThread2 implements Runnable { 36 37 /** 38 * 重写run方法 39 */ 40 @Override 41 public void run() { 42 // TODO Auto-generated method stub 43 } 44 }
3.通过Callable和Future创建线程
1 import java.util.concurrent.Callable; 2 import java.util.concurrent.FutureTask; 3 4 public class Thread2Callable { 5 public static void main(String[] args) { 6 //创建 Callable 实现类的实例 7 MyCallable myCallable = new MyCallable(); 8 //使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值 9 FutureTask<String> futureTask = new FutureTask<String>(myCallable); 10 String res = null; 11 try { 12 //使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程 13 //没这句,下句代码获取不到结果,会一直等待执行结果 14 new Thread(futureTask,"线程1").start(); 15 //调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值 16 res = futureTask.get(); 17 } catch (Exception e) { 18 e.printStackTrace(); 19 } 20 System.out.println(res); 21 } 22 } 23 /** 24 * 创建 Callable 接口的实现类,并实现 call() 方法 25 */ 26 class MyCallable implements Callable<String> { 27 28 /** 29 * 该 call() 方法将作为线程执行体,并且有返回值 30 */ 31 @Override 32 public String call() throws Exception { 33 return "success"; 34 } 35 }
Runnable和Callable的区别和联系
接口定义
其中Runnable应该是我们最熟悉的接口,它只有一个run()函数,用于将耗时操作写在其中,该函数没有返回值。然后使用某个线程去执行该runnable即可实现多线程,Thread类在调用start()函数后就是执行的是Runnable的run()函数。
Runnable的声明如下 :
1 public interface Runnable { 2 /* 3 * @see java.lang.Thread#run() 4 */ 5 public abstract void run(); 6 }
#Callable
Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是call()函数有返回值,而Runnable的run()函数不能将结果返回给客户程序。
Callable的声明如下 :
1 public interface Callable<V> { 2 /** 3 * Computes a result, or throws an exception if unable to do so. 4 * 5 * @return computed result 6 * @throws Exception if unable to compute a result 7 */ 8 V call() throws Exception; 9 }
#Future
Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行
取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。
Future声明如下 :
1 public interface Future<V> { 2 3 /** 4 * Attempts to cancel execution of this task. This attempt will 5 * fail if the task has already completed, has already been cancelled, 6 * or could not be cancelled for some other reason. If successful, 7 * and this task has not started when <tt>cancel</tt> is called, 8 * this task should never run. If the task has already started, 9 * then the <tt>mayInterruptIfRunning</tt> parameter determines 10 * whether the thread executing this task should be interrupted in 11 * an attempt to stop the task. 12 */ 13 boolean cancel(boolean mayInterruptIfRunning); 14 15 /** 16 * Returns <tt>true</tt> if this task was cancelled before it completed 17 * normally. 18 */ 19 boolean isCancelled(); 20 21 /** 22 * Returns <tt>true</tt> if this task completed. 23 * 24 */ 25 boolean isDone(); 26 27 /** 28 * Waits if necessary for the computation to complete, and then 29 * retrieves its result. 30 * 31 * @return the computed result 32 */ 33 V get() throws InterruptedException, ExecutionException; 34 35 /** 36 * Waits if necessary for at most the given time for the computation 37 * to complete, and then retrieves its result, if available. 38 * 39 * @param timeout the maximum time to wait 40 * @param unit the time unit of the timeout argument 41 * @return the computed result 42 */ 43 V get(long timeout, TimeUnit unit) 44 throws InterruptedException, ExecutionException, TimeoutException; 45 }
#FutureTask(很有用)
FutureTask是一个RunnableFuture<V>
1 public class FutureTask<V> implements RunnableFuture<V>