目录
9.3 wait()/notify()/notifyAll()用法
1、进程和线程的基本概念
1.1进程
-
运行中的应用程序叫进程,每个进程运行时,进程负责了内存空间的划分。它是系统进行资源分配和调度的一个独立单位。
-
操作系统都是支持多进程的
-
Windows是多任务的操作系统,那么Windows是同时运行多个应用程序吗?
1.2线程
1.2.1线程概念和特点
-
线程是轻重级的进程,是进程中一个负责程序执行的控制单元
-
线程是由进程创建的(寄生在进程中)
-
一个进程可以拥有多个线程,至少一个线程
-
线程有几种状态(新建new,就绪Runnable,运行Running,阻塞Blocked,死亡Dead)
-
开启多个线程是为了同时运行多部分代码,每个线程都 有自已的运行的内容,这个内容可以称线程要执行的任务。
打开360卫士,就是打开一个进程,一个进程里面有很多代码,这些代码就是谁来执行的呢?线程来执行这些代码。
1.2.2 多线程
-
多线程:在一个进程中有多个线程同时在执行不同的任务。
-
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务,如:百度网盘、腾讯会议。
-
同时执行多个任务的优势:减低CPU的闲置时间,从而提高CPU的利用率
2.多线程的优缺点
2.1 多线程优点
-
Java支持编写多线程的程序;
-
多线程最大的好处在于可以同时并发执行多个任务;
-
多线程可以最大限度地减低CPU的闲置时间,从而提高CPU的利用率
2.2 多线程缺点
-
线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
-
多线程需要协调和管理,所以需要CPU时间跟踪线程;
-
线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
-
线程太多会导致控制太复杂,最终可能造成很多Bug
3.主线程
-
Java支持多线程
-
主线程的特殊之处在于:
任何一个Java程序启动时,一个线程立刻运行,它执行main方法,这个线程称为程序的主线程。
一个Java应用程序至少有两个线程,一个是主线程负责main方法代码执行;一个是垃圾回收器线程,负责了回收垃圾。
4.创建线程
4.1 创建线程的三种方式
-
方式一:继承Thread类
-
方式二:实现Runnable接口
-
方式三:实现Callable接口
4.2 继承Thread类
-
继承Java.lang.Thread类,并重写run() 方法。
-
案例1:打印输出0-100的数字,创建两个线程交替执行
//线程类
public class MyPrintTread extends Thread {
//构造方法,传入线程名称
public MyPrintTread(String name) {
super(name);
}
//重写run方法,线程会调用run方法
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
try {
Thread.sleep(1000);//休眠1秒钟,阻塞代码,单位毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
//this.getName()获取线程名称
System.out.println(this.getName() + ":" + i);
}
}
}
public class MyThreadTest {
public static void main(String[] args) {
//创建2个线程类对象
MyPrintTread thread1 = new MyPrintTread("线程1");
MyPrintTread thread2 = new MyPrintTread("线程2");
//start方法
//1、start方法,让操作系统启动一个线程执行MyPrintThread对象run方法
//2、start方法调用之后不会立刻启动一个线程,线程的启动取决于操作系统
thread1.start();
thread2.start();
//打印main方法执行完毕
System.out.println("main方法执行完毕");
}
}
运行结果:
main方法执行完毕
线程1:1
线程2:1
线程1:2
线程2:2
线程2:3
……
线程2:99
线程1:99
线程1:100
线程2:100
- 案例2:模拟龟兔赛跑
兔子线程
public class MyThread1 extends Thread {
private int s = 5;
@Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) { //永真循环
if (s < 0) { //s小于0,跑完全程
System.out.println("兔子跑完了");
break; //结束线程
}
System.out.println("兔子领先了,加油,还剩下" + s + "米");
s--;
}
}
}
乌龟线程
public class MyThread2 extends Thread {
private int s = 5;
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (s < 0) {
System.out.println("乌龟跑完了");
break;
}
System.out.println("乌龟领先了,加油,还剩下" + s + "米");
s--;
}
}
}
测试类
public class RaceThreadTest {
public static void main(String[] args) {
//创建兔子线程
MyThread1 thread1 = new MyThread1();
thread1.start();
//创建乌龟线程
MyThread2 thread2 = new MyThread2();
thread2.start();
}
}
运行截图: