多线程
多线程的概念
多线程是一种用于实现并发执行的计算机编程技术,这允许单个程序创建和管理多个线程,以同时执行多个任务或执行块。
- 并发:在同一时刻,有多个指令在单个CPU上交替执行
- 并行:在同一时刻,有多个指令在CPU上同时执行
线程的生命周期
- 新建(New):创建后尚未启动的线程处于这个状态
- 就绪(Runnable):调用start()方法后,线程进入就绪状态,此时线程只是开辟了内存空间,正在等待被线程调度器选中获得对CPU的使用权
- 运行(Running):线程获得CPU权限进行执行
- 阻塞(Blocked):线程因为某些原因放弃CPU使用权,暂时停止运行,直到线程进入就绪状态才有机会转到运行状态
- 死亡(Terminated):线程执行结束或者因为异常退出的状态
多线程的实现方式
-
继承Thread类的方式进行实现
- 自己定义一个类继承Thread
- 重写run方法
- 创建子类对象,并启动线程
//定义一个类继承Thread
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName());
}
}
}
//开启线程
public class Main {
public static void main(String[] args) {
创建MyThread对象
MyThread t1 = new MyThread();
//设置线程名字
t1.setName("线程1");
//可以合并写:
//MyThread t1 = new MyThread("线程1")
//开启线程
t1.start();
}
}
-
实现Runnable接口的方式进行实现
- 自己定义一个类实现Runnable接口
- 重写run方法
- 创建自己定义的类的对象
- 创建一个Thread类的对象,并开启线程
//定义一个类实现Runnable接口
public class MyRun implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//获取到当前线程的对象
Thread t = Thread.currentThread();
System.out.println(t.getName());
}
}
}
//开启线程
public class Main {
public static void main(String[] args) {
//创建MyRun对象
MyRun mr = new MyRun();
//创建线程对象
Thread t1 = new Thread(mr);
//给线程设置名字
t1.setName("线程1");
//开启线程
t1.start();
}
}
-
利用Callable接口和Future接口方式实现
- 特点:可以获取多线程运行的结果
- 自己定义一个类实现Callable接口
- 重写call(有返回值,表示多线程运行的结果)
- 创建自己定义的类的对象(表示多线程要执行的任务)
- 创建FutureTask的对象(管理多线程运行的结果)
- 创建Thread类的对象,并启动(表示线程)
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
}
public class Main {
public static void main(String[] args) {
//创建MyCallable对象(表示多线程要执行的任务)
MyCallable mc = new MyCallable();
//创建FutureTask对象(管理多线程运行的结果)
FutureTask<Integer> ft = new FutureTask<> ();
//创建线程的对象
Thread t1 = new Thread(ft);
//启动线程
t1.start();
//获取多线程运行的结果
Integer result = ft.get();
System.out.println(result);
}
}
三种实现方式的比较
| 优点 | 缺点 | |
|---|---|---|
| 继承Thread类 | 编程比较简单,可以直接使用Thread类中的方法 | 可以扩展性较差,不能再继承其他类 |
| 实现Runnable接口 | 扩展性强,实现该接口的同时还可以继承其他的类 | 编程相对复杂,不能直接使用Thread类中的方法 |
| 实现Callable接口 | 扩展性强,实现该接口的同时还可以继承其他的类 | 编程相对复杂,不能直接使用Thread类中的方法 |
多线程中常用的成员方法
- 返回此线程的名称
String getName()
- 设置线程的名字(构造方法也可以设置名字)
void setName(String name)
- 获取当前线程的对象
当JVM虚拟机启动之后,会自动的启动多条线程,其中有一条线程就叫做main线程,它的作用就是去调用main方法,并执行里面的代码
static Thread currentThread()
- 让线程休眠指定的时间,单位为毫秒
static void sleep(long time)
- 设置线程的优先级
1 -> 最小
10 -> 最大
5 -> 默认
setPriority(int newPriority)
- 获取线程的优先级
final int getPriority()
- 设置守护线程
当其他的非守护线程完毕之后,守护线程回陆续结束
final void setDaemon(boolean on)
- 出让线程/礼让线程
public static void yield()
- 插入线程/插队线程
public static void join()