Day21-1
1 多线程相关的三组概念
1.1 程序和进程
- 程序:定义的一些可以用来运行的可执行文件。
程序不启动,就不会分配内存和系统资源。 - 进程:一个正在运行的程序就是进程。
一个进程运行之后,是有内存的分配和系统资源的分配。
1.2 进程和线程
- 进程:正在执行的程序。
- 线程:进程中的一条独立的执行单元。
举例:
班级:进程
学生A: 线程
学生B: 线程
学生C 线程
特点:
(1)进程是有线程组成的
(2)进程中至少有一条线程
(3)进程之间互不影响,资源不共享
(4)一个进程中的线程,资源共享
(5)如果一个进程中有一条线程,那么该进程就是一个单线程进程
(6)如果一个进程中有多条线程,那么该进程是一个多线程进程
比如:在软件中启动一个程序,该程序中就只有一个主方法需要执行,启动该程序之后,就变为一个进程,那么该进程是一个多线程进程
启动程序之后,JVM调用了主线程main来执行内容
默认调用一个垃圾回收线程来回收内存中的垃圾数据
1.3 并行和并发
-
并行:在某一个时刻,多个进程(线程)同时在执行。
举例:在9:16:10
同学A在睡觉
同学B在学习
同学C在走神
问题:如果计算机想要实现并行,需要什么条件?
需要多个cpu -
并发:在某一个时刻,多个进程(线程)同时启动,同时启动的多个任务会被cpu交替执行。
要求:同学A在某一个时刻,去学习、去睡觉、去吃饭、去打游戏
问题:只有一个cpu,使用并发的方式,提高了系统的运行效率还是降低了?
整体提高了系统的运行效率
2 多线程的第一种实现方式
- 方式:继承方式
- 步骤:
(1)自定义一个线程类型
(2)继承Thread类型
(3)重写父类中的run方法表示一个具体的任务
(4)在主方法中创建一个线程类对象
(5)启动线程 - 注意事项:
(1)新线程的创建和启动,需要借助主线程
(2)一旦新线程启动之后,两个线程之间互不影响,cpu去谁那谁就执行
(3)启动线程的方法:start(); - 图示:
代码
package demos1;
public class Demo01 {
public static void main(String[] args) {
//4、创建一个自定义类对象(新线程对象)
MyThread mt = new MyThread();
//5、启动新线程
mt.start();
for(int i = 1;i <= 1000;i++){
System.out.println(i + "main线程执行的任务");
}
}
}
//1、定义一个类型
//2、需要继承Thread类型
//3、重写父类的run方法
class MyThread extends Thread{
@Override
public void run() {
for(int i = 1;i <= 1000;i++){
System.out.println("新线程执行的任务:" + i);
}
}
}
3 多线程的第二种实现方式
- 方式:实现方式
- 步骤:
(1)定义一个类型,表示一个任务类
(2)实现Runnable接口
(3)重写接口中的run方法表示需要执行的任务
(4)在方法中创建一个任务类对象,表示一个具体任务
(5)创建一个Thread类的线程对象,将任务对象提交给线程对象
(6)启动线程
代码
package demos1;
public class Demo02 {
public static void main(String[] args) {
//4、创建一个自定类对象(任务类)
MyTask mt = new MyTask();
//5、创建一个线程,将任务提交给该线程执行
Thread t = new Thread(mt);
//6、启动线程,默认执行提交的任务
t.start();
for(int i = 1;i <= 100;i++){
System.out.println(i + "主线程执行的任务");
}
}
}
//1、定义一个类型
//2、实现一个接口:Runnable
//3、重写接口中的run方法
class MyTask implements Runnable{
@Override
public void run() {
for(int i = 1;i <= 100;i++){
System.out.println("新线程需要执行的任务:" + i);
}
}
}
4 继承的方式和实现的方式区别
- 程序的复杂度:
继承的方式比较简单,直接创建一个线程对象启动即可
实现的方式稍微复杂,创建一个任务对象之后,需要再创建一个线程对象,再将任务提交给线程,最后启动。 - 程序的灵活性:
继承的方式灵活性弱:线程类创建的对象只能执行类中定义好的任务,是固定不变的
实现的方式灵活性强:在创建一个任务对象之后,这个任务对象可以提交给不同的线程 执行;在创建一个线程之后,可以接收不同的任务执行 - 程序的扩展性:
继承的方式,不能再继承其他父类,扩展性弱
实现的方式,可以继续继承其他父类,扩展性强
5 多线程的第三种创建方式
- 实现Callable接口
- 步骤:
(1)定义一个类实现Callable接口
(2)在类中重写call()方法
(3)创建自定义类的对象
(4)创建Future的实现类FutureTask对象,把自定义类对象作为构造方法的参数传递
(5)创建Thread类的对象,把FutureTask对象作为构造方法的参数传递
(6)启动线程
(7)再调用get方法,就可以获取线程结束之后的结果。 - 和前两种定义的区别:
实现的call方法是可以定义返回值
代码
package demos1;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Demo03 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//4、创建一个人物类对象
MyCallable mc = new MyCallable();
//5、将创建的任务对象进行包装
FutureTask<String> fu = new FutureTask<String>(mc);
//6、将包装之后的任务,提交给线程执行
Thread t = new Thread(fu);
//7、启动线程
t.start();
//8、获取任务执行之后的返回值
// 获取的结果要在线程启动之后执行
String str = fu.get();
System.out.println(str);
}
}
//1、定义一个类型表示一个任务类
//2、实现接口:Callable接口
//3、重写接口中的方法,该方法表示需要执行的任务
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
for(int i = 1;i <= 100;i++){
System.out.println("我已经向我的女神表白了" + i + "次");
}
return "恭喜你,女神同意了!";
}
}
匿名内部类实现多线程
package demos1;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Demo04 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//3、使用匿名内部类创建一个带着返回值的任务对象
Callable<String> call = new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("这是新线程需要执行的任务");
return "新线程执行结束了";
}
};
FutureTask<String> fu = new FutureTask<>(call);
Thread t = new Thread(fu);
t.start();
System.out.println(fu.get());
}
private static void test02() {
//2、使用匿名内部类创建一个任务对象
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("新线程需要执行的任务");
}
};
Thread t = new Thread(r);
t.start();
}
private static void test01() {
//1、使用匿名内部类的方式代替第一种写法
Thread t = new Thread(){
@Override
public void run(){
System.out.println("新线程需要执行的任务");
}
};
t.start();
}
}