1.概述
多线程是指从软件或者硬件上实现多个线程并发执行的技术。线程是程序中独立运行的程序片段,每个线程都有独立的执行流程,可以在同一时间内执行不同的任务。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。
多线程是并行化的一种形式,或者是拆分工作以便同时进行处理。线程化的程序将工作拆分到多个软件线程,而不是将大量工作交给单个内核。这些线程由不同的CPU内核并行处理,以节省时间。多线程可以提高程序的并发性和效率,实现异步处理,提高程序的响应速度和用户体验。
2.Thread类常用方法
- start():启动当前线程,使其进入就绪状态,等待CPU调度执行。调用该方法将自动调用线程的run()方法。
- run():线程执行的具体操作就在这个方法中定义。通常,我们会通过继承Thread类或实现Runnable接口来重写这个方法。
- currentThread():这是一个静态方法,用于返回当前正在执行的线程对象。
- getName():获取当前线程的名字。
- setName(String name):设置当前线程的名字。注意,这个设置通常在调用start()方法之前进行。
- yield():使当前线程放弃CPU的执行权,让其他线程有机会执行。这并不意味着当前线程不再执行,而是让出CPU时间片,等待下一次调度。
- join():在线程A中调用线程B的join()方法,会导致线程A等待,直到线程B执行完毕。这可以用来实现线程之间的同步。
- sleep(long millis):让当前线程休眠指定的毫秒数。在这段时间内,线程不会执行任何操作,也不会被调度。
- isAlive():判断当前线程是否还在执行。如果线程已经结束,该方法将返回false。
- interrupt():中断当前线程。如果线程正在执行阻塞操作(如sleep、wait、join等),中断会使其收到一个InterruptedException异常。
3.创建多线程的三种方式
创建子线程图解:
1. 继承Thread类:
实现步骤:
1.继承Thread类并重写run方法
public class MyThread extends Thread {
@Override
public void run(){
for(int i=0;i<10;i++){
System.out.println("子线程"+i);
}
}
}
2.实例化Thread类
3.启动线程
public class CreateThread01 {
public static void main(String[] args) {
Thread Thread = new MyThread();//创建线程
Thread.start();//启动线程线程
for(int i=0;i<10;i++){
System.out.println("主线程"+i);
}
}
}
2.实现Runnable接口:
实现Runnable接口的类作为任务类然后通过Thread类的实例来运行这个任务类。这种方式更推荐,因为它避免了单一继承的限制,更便于共享资源。
实现步骤:
1.实现Runnable接口,重写run方法
public class MyRunable implements Runnable {
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println("子线程"+i);
}
}
}
2.实例化Runable类
3.传入Runable类参数实例化Thread类
4.启动线程
public class CreateThread02 {
public static void main(String[] args) {
//写法一
// Runnable runable = new MyRunable();//实例化Rubable的子类,创建任务对象
// new Thread(runable).start();//创建线程,将任务对象交给线程对象处理并启动线程
//写法二,接口的匿名类写法
new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println("子线程"+i);
}
}
}).start();
for(int i=0;i<10;i++){
System.out.println("主线程"+i);
}
}
}
3.利用Callable接口:
Callable接口是类似于Runnable的接口,实现Callable接口的类和实现Runnable接口的类都是可以被其它线程执行的任务。通过实现Callable接口可以获取返回值,并可以抛出异常。
实现步骤:
1.实现Callable接口重写call方法并通过泛型指定返回值类型,这里的call类似run方法。
import java.util.concurrent.Callable;
public class MyCallable implements Callable<String> {
private int n;
MyCallable(int n){
this.n=n;
}
@Override
public String call() throws Exception {
int sum=0;
for(int k=0;k<n;k++){
sum++;
}
return Thread.currentThread().getName()+"执行结果"+sum;
}
}
2.实例化未来任务类FutureTask
3.实例化Thread类来运行未来任务类
4.启动线程
5.获取返回值
import jdk.nashorn.internal.codegen.CompilerConstants;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CreateThread03 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建Callable对象
Callable<String> callable = new MyCallable(100);
//创建未来任务对象
FutureTask<String> f1=new FutureTask(callable);
//封装任务对象并启动线程
new Thread(f1,"子线程1").start();
//获取线程执行结果
System.out.println(f1.get());
Callable<String> callable2 = new MyCallable(200);
FutureTask<String> f2=new FutureTask(callable2);
new Thread(f2,"子线程2").start();
System.out.println(f2.get());
}
}
执行结果