实现多线程的3种方式
- 并发和并行
- 继承Thread类
- 实现Rannble接口
- 利用Callable接口和Future接口
一段程序的运行过程是一个进程,而一个过程可以由多个线程组成。例如一个软件的运行是一个进程,而软件中的各种功能可以认为是构成进程的多个线程
在以前我们的单线程程序中,我们的代码在运行的时候会和内存进行交互,此时我们的CPU就只能进行等待,而在多线程的程序中我们的CPU在空闲的时间回去执行别的线程的程序而不会去等待,提高了对CPU的利用率
并发和并行
1个CPU交替执行多条线程
2个线程在2个CPU上同时执行
实际上我们的电脑并不是只能运行一个线程,根据CPU一次可以执行多少线程,可以有以下分类:
- 并行
当我们的2核4线程的CPU只有4条线程在执行时,此时是并行
当我们要执行的线程多余4条将会并发执行,将会在这些线程中随机切换执行。即并发执行所以说在我们计算机中并发和并行其实都存在
第一种实现--继承Thread类
Thread类表示线程,当我们的类继承自Tread即可以表现出多线程。要求实现Thread类的run方法,线程将执行run方法中的内容,必须要使用start方法启动线程
package com.cook.test;
public class MyThread1 extends Thread{
public MyThread1(){};
public MyThread1(String threadname){
super(threadname);
}
@Override
public void run(){
for (int i = 0; i < 10; i++) {
System.out.println(this.getName()+"hello world!");
}
}
}
package com.cook.test;
public class MyThreadTest1 {
public static void main(String[] args) {
MyThread1 t1 = new MyThread1();
MyThread1 t2 = new MyThread1();
t1.start();
t2.start();
}
}
其实这里有3个线程抢夺CPU资源,main方法也是一个线程。从输出可以看出t1 t2这2给线程争夺CPU的情况
实现Runnable接口
其实继承Thread类实现多线程有一个弊端,因为如果一个类继承了Thread类将不能实现别的类,这将会到来极大的局限性,可以用实现Runnalb的方式来破冰
package com.cook.test;
public class MyThread2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"hello world");
}
}
}
package com.cook.test;
public class MyThreadTest2 {
public static void main(String[] args) {
MyThread2 t = new MyThread2();
Thread t1 = new Thread(t,"线程1");//要在Thread中传入我们实现了Rannable的对象(可传入线程名)
Thread t2 = new Thread(t,"线程2");//要在Thread中传入我们实现了Rannable的对象
t1.start();
t2.start();
}
}
利用Callable接口和Future接口
前面的方式解决了只能实现Thread不能有别的接口的问题,但是我们的run方法没有返回值,我们有些时候是需要run方法的返回值的
package com.thread.case1;
import java.util.concurrent.Callable;
public class MyCallable implements Callable<Integer> {//泛型表示线程要返回的类型
@Override
public Integer call() throws Exception {//这个相当于run方法里面写执行多线程的代码
//计算1-100的和
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum+=i;
}
return sum;
}
}
package com.thread.case1;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadTest3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
/* 多线程第三种实现:可以获取多线程的运行结果
1.创建一个类MyCallable实现Callable接口
2.重写call(是有返回值的,表示多线程的运行结果)
3.创建MyCallable的对象(表示多线程要执行的任务)
4.创建FutureTask的对象(作用管理多线程运行的结果)
5.创建Thread类的对象,并启动线程*/
MyCallable ma = new MyCallable();
FutureTask<Integer> ft = new FutureTask<>(ma);
Thread td = new Thread(ft);
td.start();
final Integer result = ft.get();//获取线程的值
System.out.println(result);
}
}