简谈多线程
文章目录
概念
多线程
多线程:在一个进程中可以同时开始多个线程,让这多个线程同一时间去执行某些任务或者功能,以此来提高执行效率。
进程;每个进程都有独立的代码和数据空间,一个进程中可以有1-n个线程。(进程是资源分配的最小单位)。
并行和并发
并行:多个任务在同一时刻点同时执行。
并发:多个任务在同一时间内分时执行线程。
多线程实现方法
1 继承Thread类
优点:编码简单
缺点:线程类继承了Thread,无法再继承其他类,不利于功能的扩展
子类代码:
//写一个子类继承Thread
public class MyThread extends Thread {
// 重写run方法
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("MyThread" + i);
}
}
测试类代码:
//测试类
public class ThreadTest1 {
public static void main(String[] args) {
//创建线程对象
MyThread myThread = new MyThread();
//启动线程
myThread.start();
for (int i = 0; i < 5; i++) {
System.out.println("main" + i);
}
}
}
测试结果:
for循环内容交叉打印输出
MyThread0
main0
MyThread1
main1
MyThread2
main2
MyThread3
main3
MyThread4
main4
2 实现Runnable 接口
优点:任务类只是实现了接口,可以继续继承其他类,实现其他接口,扩展性强
缺点:需要多一个Runnable对象,有结果不能直接返回
实现类代码:
//实现类实现Runnable接口
public class MyRunnable implements Runnable {
//重写run方法
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Runnable"+i);
}
}
}
测试类代码:
public class Test01 {
public static void main(String[] args) {
// 创建MyRunnable任务
MyRunnable myRunnable = new MyRunnable();
Thread mr = new Thread(myRunnable, "myRunnable");
mr.start();
//主线程
for (int i = 0; i < 5; i++) {
System.out.println("main" +i);
}
}
}
测试结果:
Runnable0
main0
Runnable1
main1
Runnable2
main2
Runnable3
main3
Runnable4
main4
3 实现Callable接口
优点:最大的优点就是可以返回线程执行完毕后的结果
缺点:编码复杂很多。
实现类代码:
public class Mycallable implements Callable<String> {
int n;
public Mycallable(int n){
this.n=n;
}
@Override
public String call() throws Exception {
//计算数字的和
int sum = 0;
for (int i = 0; i < n; i++) {
sum+=n;
}
//Thread.currentThread().getName() 获取线程的名字
String result = Thread.currentThread().getName() + "求到的和是:" +sum;
return result;
}
}
4 创建线程池
4.1 使用ThreadPoolExecutor创建
优点:可以实时获取线程池内线程的各种状态,还可以动态的调整线程池的大小
测试类代码:
public class ThreadTest2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1.定义线程池对象
ThreadPoolExecutor tp = new ThreadPoolExecutor(
3, //核心线程数
5, //最大线程数
100, //休闲存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(3), //等待队列
Executors.defaultThreadFactory(), //创建工厂
new ThreadPoolExecutor.AbortPolicy() //默认拒绝策略
);
// 2.创建任务对象
Mycallable tc = new Mycallable(100);
// 3.执行任务
Future<String> f1 = tp.submit(tc); //如果是实现的Runnable接口,这里建议使用execute。
Future<String> f2 = tp.submit(new ThreadCallable(200));
// 4.返回执行结果
System.out.println(f1.get());
System.out.println(f2.get());
}
}
测试结果:
pool-1-thread-1求到的和是:10000
pool-1-thread-2求到的和是:19900
4.2 使用Executors的工具类创建线程
优点:创建简单
缺点:里面的最大线程数被设置为Integer.MAX_VALUE,可能会创建出大量的线程,导致OOM(内存溢出)
测试代码:
public class ThreadTest3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//定义起来方便很多,但是限制也很多
ExecutorService es = Executors.newFixedThreadPool(4);
Future<String> f1 = es.submit(new Mycallable(300));
Future<String> f2 = es.submit(new Mycallable(400));
Future<String> f3 = es.submit(new Mycallable(500));
Future<String> f4 = es.submit(new Mycallable(600));
System.out.println(f1.get());
System.out.println(f2.get());
System.out.println(f3.get());
System.out.println(f4.get());
}
}
测试结果
pool-1-thread-1求到的和是:90000
pool-1-thread-2求到的和是:160000
pool-1-thread-3求到的和是:250000
pool-1-thread-4求到的和是:360000
多线程实现方式的区别
1,Thread和Runnable区别
Thread底层是Runnable的实现类,需要进行继承,扩展性不强
2,Runnable和Callable的区别
Runnable和Callable都是接口,但是Callable可以捕获处理异常信息并返回结果,Runnable不能抛出运行时的异常,且无法捕获处理异常。
线程池生命周期
状态总结:
1,NEW 新建
线程刚被创建,但是并未启动。
2,Runnable 可运行
线程已经调用了start(),等待CPU调度
3,Blocked 锁阻塞
线程在执行的时候未竞争到锁对象,则该线程进入Blocked状态;
4,Waiting 无限等待
一个线程进入Waiting状态,另一个线程调用notify或者notifyAll方法才能够唤醒
5,Timed Waiting 计时等待
同waiting状态,有几个方法(sleep,wait)有超时参数,调用他们将进入Timed Waiting状态。
6 ,Terminated 被终止
因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。
生命周期图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z3fdFVMD-1690452355700)(C:\Users\13601\AppData\Roaming\Typora\typora-user-images\image-20230727180234014.png)]
g 无限等待
一个线程进入Waiting状态,另一个线程调用notify或者notifyAll方法才能够唤醒
5,Timed Waiting 计时等待
同waiting状态,有几个方法(sleep,wait)有超时参数,调用他们将进入Timed Waiting状态。
6 ,Terminated 被终止
因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。
生命周期图:
本文只简单的说了一下多线程的部分内容,感谢各位大佬的观看,文中如有问题,请各位大佬多多斧正!!!再次感谢!!!