一、JAVA 中常用的多线程实现方式
了解完什么是多线程之后,接下来该如何实现多线程呢?JAVA 语言专门提供了操作多线程功能的类和接口,通过查看 API ,可以发现在 Java.lang 包 下的 Thread 类和 Runnable 接口就是专门实现此功能的。
-
实现多线程的两种方式(只实现多线程,不包含任何方法和功能,最简单的实现)
- 方式一:继承 Thread 类
- 方式二:实现 Runnable 接口
1、方式一:继承 Thread 类
-
实现多线程的步骤:
- 1、自定义一个类,继承 Thread 类,使其成为一个线程类
- 2、在这个子类中重写 Thread 类的 run() 方法
- 3、创建 Thread 类的子类的对象。
- 4、通过此对象调用 start() 方法来启动一个线程。
- run() 方法和 start() 方法
-
run()方法
- run() 方法,可以理解为这个方法就是一个空方法,是搭配 start() 方法使用的。
-
start() 方法
- 通过该方法启动线程的同时也创建了一个线程,然后会在该线程中执行 run() 方法的内容,而主线程照常执行,是真正实现了多线程的方法。
-
- Demo代码
//总结:注意,线程开启后不一定会立刻执行,由 CPU 进行调度执行。 // 第一步,继承Thread类 public class TestThread extends Thread{ // 第二步,重写 run() 方法 @Override public void run() { for (int i = 1; i <= 10; i++) { System.out.println("我正在编写多线程代码"+ i); } } //程序主线程 main线程 public static void main(String[] args) { // 第三步:创建子类对象 TestThread1 thread = new TestThread1(); //第四步:调用start()方法启动线程的同时也创建了一个线程,真正实现了多线程 thread.start(); for (int i = 1; i <= 10; i++) { System.out.println("我正在学习多线程"+ i); } } }
运行结果:
在这里观察一下运行的结果,可以发现两个方法中的两个for循环遍历出来的数据都打印在了控制台上。并且多运行几次还可以发现,打印的还没啥规律,这就说明了程序的进程中存在两条线程,但是程序的出口只有一个。两条线程一起执行,到出口时候线程中的数据会陆续从程序的出口出来,谁先出来就先将谁打印出来。
2、方式一:实现 Runnable 接口(推荐用法)
-
实现多线程的步骤:
-
1、创建一个Runnable接口的实现类,使其成为一个线程类
-
2、在这个实现类中实现 Runnable 类的抽象方法: run() 方法
-
3、创建实现类的对象。
-
4、创建 Thread 类的对象,并把实现类对象作为构造参数传递到 Thread 类的构造方法中
-
5、通过 Thread 类对象调用start()方法来启动线程。
- Demo代码
public class TestRunnable implements Runnable{ //run()方法线程 @Override public void run() { for (int i = 1; i <= 10; i++) { System.out.println("我正在编写多线程代码"+ i); } } //程序主线程 main 线程 public static void main(String[] args) { // 创建 Runnable 接口实现类对象 TestRunnable tr = new TestRunnable(); // 创建线程对象,通过线程对象来开启线程,是代理的方式 /* Thread thread = new Thread(tr); thread.start(); */ //上面两行代码可以简写成下面这一行代码 new Thread(tr).start(); for (int i = 1; i <= 10; i++) { System.out.println("我正在学习多线程"+ i); } } }
-
运行结果:
3、分析为什么推荐使用 Runnable 接口来实现多线程
为啥子推荐使用实现 Runnable 接口的方式来实现多线程?
-
Java 语言不能实现类的多继承,但可以实现接口的多实现
-
如果使用继承 Thread 类的方式实现多线程,其实现的过程会重写 run() ,并在其中实现业务代码,将父类 run() 的跳转功能覆盖掉。并且因为其无法实现多继承,局限性很高。
-
而使用实现 Runnable 接口来实现多线程,实现类会实现其接口的 run() 方法,并且接口可以多实现,大大减小了局限性,并且还降低了程序耦合性。
-
在 Runnable 接口中只有一个抽象方法,如果实现 Runnable 接口的话,只需要实现接口中的抽象方法即可,并且其他 Runnable 接口的实现类中的方法也可以直接使用。
-
使用实现 Runnable 接口来实现多线程的方法适合多线程处理同一资源 ,并且代码可以被多线程共享,数据独立,很容易实现资源共享