多线程是java中比较重要的一部分内容,使用多线程有许多的优点:
- 提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
- 程序需要实现一些需要等待的任务时,可以提高计算机系统CPU的利用率
- 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
本文就多线程来做一个总结,希望可以给予大家一些帮助。
一、多线程的概述和创建
1. 基本概念:程序-进程-线程
- 程序(program) 是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。
进程(process) 是程序的一次动态执行过程,它经历了从代码加载、执行到完毕的一个完整过程。动态过程:有它自身的产生、存在和消亡的过程。
如:运行中的QQ,运行中的MP3播放器
程序是静态的,进程是动态的线程(thread)进程可进一步细化为线程,是一个程序内部的一条执行路径。 是实现并发的机制的一种有效手段。
若一个程序可同一时间执行多个线程,就是支持多线程的
2. 线程的创建和启动
在java中实现多线程可以采用两种方式:继承Thread类、实现Runnable接口
3. Thread类
- Thread类是在java.lang包中定义的, 所以不需要导入,一个类只要继承了继承Thread类, 就是一个多线程操作类
- 子类中重写Thread类中的run方法, 此方法为线程的主体。
- 创建Thread子类对象,即创建了线程对象。
- 调用线程对象start方法:启动线程,并调用run方法;并且start方法只能被执行一次。
class MyThread extends Thread { // 继承Thread类,作为线程的实现类
private String name; // 表示线程的名称
public MyThread(String name) {
this.name = name; // 通过构造方法配置name属性
}
public void run() { // 覆写run()方法,作为线程 的操作主体
for (int i = 0; i < 10; i++) {
System.out.println(name + "运行,i = " + i);
}
}
};
public class ThreadDemo02 {
public static void main(String args[]) {
MyThread mt1 = new MyThread("线程A "); // 实例化对象
MyThread mt2 = new MyThread("线程B "); // 实例化对象
mt1.start(); // 调用线程主体
mt2.start(); // 调用线程主体
}
};
Output:
线程A 运行,i = 0
线程B 运行,i = 0
线程A 运行,i = 1
线程B 运行,i = 1
线程A 运行,i = 2
线程B 运行,i = 2
线程B 运行,i = 3
线程B 运行,i = 4
线程A 运行,i = 3
线程B 运行,i = 5
线程A 运行,i = 4
线程B 运行,i = 6
线程A 运行,i = 5
线程B 运行,i = 7
线程A 运行,i = 6
线程B 运行,i = 8
线程A 运行,i = 7
线程B 运行,i = 9
线程A 运行,i = 8
线程A 运行,i = 9
从例子来看, 确实是并发执行的, 哪个线程先抢到cpu资源, 哪个线程就先执行。
问题:为什么不直接调用run()
方法, 而是通过start()
方法来调用(或者说start()
方法是怎么实现能启动多线程这个功能的)?-批注1
4. Runnable 接口
- 定义子类,实现Runnable接口。
- 子类中重写Runnable接口中的run方法。
- 通过Thread类含参构造器创建线程对象。
- 将Runnable接口的子类对象作为实际参数传递Thread类的构造方法中。
- 调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法。
class MyThread implements Runnable { // 实现Runnable接口,作为线程的实现类
private String name; // 表示线程的名称
public MyThread(String name) {
this.name = name; // 通过构造方法配置name属性
}
public void run() { // 覆写run()方法,作为线程 的操作主体
for (int i = 0; i < 10; i++) {
System.out.println(name + "运行,i = " + i);
}
}
};
public class RunnableDemo01 {
public static void main(String args[]) {
MyThread mt1 = new MyThread("线程A "); // 实例化对象
MyThread mt2 = new MyThread("线程B "); // 实例化对象
Thread t1 = new Thread(mt1); // 实例化Thread类对象
Thread t2 = new Thread(mt2); // 实例化Thread类对象
t1.start(); // 启动多线程
t2.start(); // 启动多线程
}
};
OUtput:
线程B 运行,i = 0
线程A 运行,i = 0
线程B 运行,i = 1
线程A 运行,i = 1
线程B 运行,i = 2
线程A 运行,i = 2
线程A 运行,i = 3
线程A 运行,i = 4
线程A 运行,i = 5
线程A 运行,i = 6
线程A 运行,i = 7
线程A 运行,i