1.多线程:
多线程
首先需要理解 进程!
进程: 我们应用程序的执行实例!有自己独立的内存空间和系统资源!
一个进程是由一个或者N个线程组成的!
线程:cpu调度和分配的基本单位!电脑中真正执行的是 线程!
在同一个时间点,我们的电脑只能运行一个线程!
多线程:
如果在一个进程中,同时运行多个线程,来完成不同的工作,我们称之为多线程!
CPU上能同时运行多个线程吗? 不能!
一个CPU在同一个时间点,只能运行一个线程,但是线程运行的速度太快,我们肉眼无法分辨
所以我们认为是多线程!
生活中进入地铁站的例子:
场景1:现在地铁站有1个进站口,同时来了5个人旅客!
需要排队进站!
场景2:现在地铁站有5个进站口,同时来了5个人旅客!
不需要排队进站!
哪个对我们的体验好点呢?
哪个地铁的设计比较合理呢?
地铁站 :CPU
进站口 :线程
多线程的好处:
01.充分的利用了CPU的资源
02.给用户带来了良好的体验
实现多线程的方式:
01.继承Thread类
02.实现Runnable接口
Thread类 implements Runnable接口
Runnable接口中
01. 只有一个方法run()
02. 没有返回值
03. 没有声明异常,其实现类的run()如果出现了 异常不能声明,只能try catch
run()和 start()的区别:
run():
01.就是一个普通的方法,称之为线程体!
02.CPU分配给当前线程时间片的时候,run()开始执行
start():
01.启动线程,不是立即执行线程!
02.底层会默认执行run()
线程的生命周期:
01.新生状态
MyThreadDemo t1 = new MyThreadDemo();
02.就绪状态
t1.start();
03.运行状态
run();
04.阻塞状态
sleep ,yield, wait , join
05.死亡状态
001.正常死亡 run()执行完毕 之后
002.异常死亡 run()执行过程中,出现异常退出!
线程的调度
按照我们特定的方式给 多个线程设置CPU的使用权!
01.线程的优先级
setPriority() 优先级越高就一定先执行! 不是的! 只是一个概率问题
02.join() 让新线程加入进来
t1.join() :必须等待t1线程执行完毕之后,其他的线程才能执行!
03.线程的休眠
sleep() 线程调用的时候,占用CPU资源不释放!其他线程就无法获取CPU资源了!
其他线程需要等待!
wait() 是Object类中的方法! 线程调用wait() 的时候,释放占用的CPU资源!
01.其他线程继续执行!无需等待!
02.使用了wait() 的线程,必须notify唤醒才能继续进入就绪状态!
04.线程的礼让 yield
概率问题,我们t1线程想让t2线程执行,有可能t2不接收这个让渡!还是t1执行!
05.线程的终止
001. interrupt : 设置线程的中断状态,不会终止,线程会继续执行!
如果有线程调用这个方法,那么这个线程的状态就是 中断状态!
我们怎么知道这个线程是不是中断状态呢???
isInterrupted可以判断线程的状态!
002. interrupted:返回线程上次的中断状态!之后清除线程的中断状态!
003. isInterrupted:返回线程是否是中断状态!
004. wait(),sleep()如果执行了,会自动清除线程的中断状态!
2.代码:
/**
* 01.继承Thread类
*/
public class MyThreadDemo extends Thread {
/**
* 重写父类的run()
*/
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + "执行了====》"
+ i);
}
}
// 多线程的并发执行
public static void main(String[] args) {
// 创建两个线程对象
MyThreadDemo t1 = new MyThreadDemo();
MyThreadDemo t2 = new MyThreadDemo();
/**
t1.run();
t2.run(); 这样调用run() 就是普通的方法,一个方法不执行完毕,另一个方法无法执行!所以顺序执行!
*/
// 真正的启动线程 是调用线程类(继承了Thread类或者实现了Runnable接口)的start()
t1.setName("第1个线程");
t2.setName("第2个线程");
t1.start();
t2.start();
}
}
/**
* 02.实现Runnable接口
*/
public class MyRunnableDemo implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + "执行了====》"
+ i);
}
}
// 多线程的并发执行
public static void main(String[] args) {
// 创建线程类对象
MyRunnableDemo demo1 = new MyRunnableDemo();
MyRunnableDemo demo2 = new MyRunnableDemo();
// 创建线程对象
Thread t1 = new Thread(demo1, "第1个线程");
Thread t2 = new Thread(demo2, "第2个线程");
// 启动线程
t1.start();
t2.start();
}
}
public class MyThread {
/**
* 主线程的入口
*/
public static void main(String[] args) {
// 获取当前执行的线程
Thread t = Thread.currentThread();
System.out.println("当前线程的名称是====》:" + t.getName());
// 设置线程名称
t.setName("主线程Main");
System.out.println("当前线程的名称是====》:" + t.getName());
}
}
3.线程的优先级
import cn.bdqn.thread.MyRunnableDemo;
/**
* 线程的优先级
* 默认是5
* 取值是1-10
* 优先级越高代表获取cpu资源的概率越高!并不代表一定高!(cpu不一定没给分配时间片)
*/
public class MyThread implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行了====》"
+ i);
}
}
// 多线程的并发执行
public static void main(String[] args) {
// 创建线程类对象
MyRunnableDemo demo1 = new MyRunnableDemo();
MyRunnableDemo demo2 = new MyRunnableDemo();
// 创建线程对象
Thread t1 = new Thread(demo1, "第1个线程");
Thread t2 = new Thread(demo2, "第2个线程");
// 获取两个线程的默认优先级
System.out.println("第1个线程的默认优先级是===》" + t1.getPriority());
System.out.println("第2个线程的默认优先级是===》" + t2.getPriority());
// 设置t1的优先级为10
t1.setPriority(10);
System.out.println("第1个线程的默认优先级是===》" + t1.getPriority());
System.out.println("第2个线程的默认优先级是===》" + t2.getPriority());
// 启动线程
t1.start();
t2.start();
}
}
4.线程的调度:
/**
* t1.sleep() :必须等待t1线程睡醒之后,其他的线程才能执行!
*/
public class SleepDemo implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {
Thread.sleep(1000); // 线程休眠1秒
System.out.println(Thread.currentThread().getName()
+ "执行了====》" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 多线程的并发执行
public static void main(String[] args) {
// 创建线程类对象
SleepDemo demo1 = new SleepDemo();
SleepDemo demo2 = new SleepDemo();
// 创建线程对象
Thread t1 = new Thread(demo1, "sleep1的线程");
Thread t2 = new Thread(demo2, "sleep2的线程");
t1.start();
t2.start();
}
}
/**
* t1.yield() :线程的礼让! 有可能对方不接受!
*/
public class YieldDemo implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行了====》"
+ i);
}
}
// 多线程的并发执行
public static void main(String[] args) {
// 创建线程类对象
YieldDemo demo1 = new YieldDemo();
Thread t1 = new Thread(demo1, "老幼病残线程");
// 启动辅助线程t1
t1.start();
for (int i = 1; i <= 100; i++) { // 在main主线程中进行输出操作
System.out.println(Thread.currentThread().getName() + "执行的i值:" + i);
if (i % 2 == 0) {
Thread.currentThread().yield(); // 主线程礼让
}
}
}
}
import cn.bdqn.thread.MyRunnableDemo;
/**
* t1.join() :必须等待t1线程执行完毕之后,其他的线程才能执行!
*/
public class JoinDemo implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行了====》"
+ i);
}
}
// 多线程的并发执行
public static void main(String[] args) {
// 创建线程类对象
MyRunnableDemo demo1 = new MyRunnableDemo();
// 创建线程对象
Thread t1 = new Thread(demo1, "join的线程");
// 启动辅助线程t1
t1.start();
for (int i = 1; i <= 10; i++) { // 在main主线程中进行输出操作
System.out.println(Thread.currentThread().getName() + "执行的i值:" + i);
if (i == 5) {
try {
t1.join(); // 阻塞主线程main !执行t1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/*
* 设置线程的中止状态
*分别实现了interrupt 设置中断状态
* interrupted:返回线程上次的中断状态!之后清除线程的中断状态!
* isInterrupted:返回线程是否是中断状态!
*/
public class InterruptDemo implements Runnable {
@Override
public void run() {
// 判断线程是否是中止状态
if (Thread.currentThread().isInterrupted()) {
System.out.println("当前线程状态是 中止状态");
} else {
for (int i = 1; i <= 50; i++) {
System.out.println(Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt(); // 设置终止状态
System.out.println(Thread.currentThread().getName()
+ "执行了====》" + i);
if (i == 2) {
Thread.currentThread().interrupted();// 清除终止状态
}
}
}
}
public static void main(String[] args) {
// 创建线程对象
InterruptDemo demo = new InterruptDemo();
Thread t = new Thread(demo);
t.start();// 启动线程
}
}