目录
继承 Tread 类,重写 run 方法
实现 Runnable 接口
使用匿名内部类,继承 Thread 类
使用匿名内部类,实现 Runable 接口
使用 Lambda 表达式
使用线程池创建线程
实现 Callable 接口
继承 Tread 类,重写 run 方法
- 自定义一个 MyThread类,用来继承 Thread 类,重写 run 方法,最后在 main 方法中new 出 MyThread 实例,并调用该实例继承自父类 Thread 类的 start 方法,从而创建一个新线程
//先创建一个类 让该类继承 Thread 父类 class MyThread extends Thread { // 重写 run 方法 @Override public void run() { System.out.println("在 run方法中 自定义线程的工作内容"); } } public class ThreadDemo1 { public static void main(String[] args) { // 创建实例t Thread t = new MyThread(); // 启动并创建新线程 t.start(); // run 方法仅执行 run方法中的代码,并不会创建一个新线程 // t.run(); } }
注意:
- 创建实例并不会直接创建一个线程,而是调用到 start 方法才会创建一个新线程
- 一个进程至少含有一个线程,JVM 默认创建线程为 主线程(main),主线程(main)与 MyThread 创建出来的新线程为并发执行,同时执行,各执行各的
实现 Runnable 接口
- 自定义一个 MyRunnable 类,用来实现 Runnable 接口,重写 run 方法,最后在 main 方法中new 出 Thread 实例,并调用该实例的 start 方法,从而创建一个新线程
class MyRunnable implements Runnable { @Override public void run() { System.out.println("在 run方法中 自定义线程的工作内容"); } } public class ThreadDemo2 { public static void main(String[] args) { // 这只是描述了个任务 Runnable runnable = new MyRunnable(); // 把任务交给线程来执行 Thread t = new Thread(runnable); t.start(); } }
注意:
- 该方式能将 线程 和 线程要干的活 之间分离开,从而达到 解耦合 的效果
- 如果要改动代码,不用使用多线程,转而使用多进程、线程池等,此时代码的改动较小
使用匿名内部类,继承 Thread 类
- 直接创建 Thread 子类,同时实例化出一个对象,重写 run 方法,并调用该实例的 start 方法,从而创建一个新线程
public class ThreadDemo3 { public static void main(String[] args) { Thread t = new Thread() { @Override public void run() { System.out.println("在 run方法中 自定义线程的工作内容"); } }; t.start(); } }
注意:
使用匿名内部类,实现 Runable 接口
- 使用匿名内部类,实现 Runnable 接口作为 Thead 构造方法的参数,最后调用实例的 start 方法,从而创建一个新线程
public class ThreadDemo4 { public static void main(String[] args) { Thread t = new Thread(new Runnable() { @Override public void run() { System.out.println("在 run方法中 自定义线程的工作内容"); } }); t.start(); } }
使用 Lambda 表达式
- lambda 本质为以一个匿名函数,()表示函数的形参,-> 为特殊语法,{ } 表示函数体,以上构成一个 lambda 表达式
public class ThreadDemo5 { public static void main(String[] args) { Thread t = new Thread(() -> { System.out.println("自定义线程的工作内容"); }); t.start(); } }
使用线程池创建线程
- ThreadPoolExecutor(线程池)的构造方法写起来很麻烦,但是标准库提供了一系列工程方法来简化其使用
- 工厂模式:将产品实例的权利移交给工厂,程序员不再通过 new 来创建所需对象,而是通过工厂获取所需产品,降低了产品使用者与使用者之间的 耦合关系
- 使用线程池不需显示的 new,而是通过 Executors 这个静态方法 new CaChedThreadPool 来完成
- 当然使用 submit 方法,将任务提交到线程池中,线程池中会有线程来完成这些任务
package Thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadDemo6 { public static void main(String[] args) { ExecutorService pool = Executors.newCachedThreadPool(); pool.submit( new Runnable() { @Override public void run() { System.out.println("在 run方法中 自定义线程的工作内容"); } }); } }
实现 Callable 接口
- 自定义一个 MyCallable 类,实现 Callable 接口,重写 call 方法(call 方法可认为是线程需要执行的任务),并且带有返回值,这个返回表示一个计算结果,如果无法计算结果,则会引发 Exception 异常
- 再创建 Callable 实例,使用FutrueTast 类包装 Callable 对象,FutureTask 是一个包装器,需要接收 Callable 实例来创建,并且有两个构造函数,一个参数只有 Callable 对象,另一个参数不仅有 Callable 对象,还有一个泛型 result 参数
- 这里使用 FutureTask 对象作为 Thread 的构造参数,通过 strat 方法创建新线程
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; class MyCallableTest implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println("创建线程:" + Thread.currentThread().getName()); return 1; } } public class ThreadDemo7 { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<Integer> task = new FutureTask<>(new MyCallableTest()); Thread t = new Thread(task); t.start(); System.out.println("创建线程的返回结果为:" + task.get()); } }