点个关注,必回关
文章目录
一、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的区别和联系
1.定义接口
(1) Runnable
其中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 }
(2)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 }
(3)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