概念介绍
- 进程:正在运行的程序
- 是系统进行资源分配和调用的独立单位。
- 每一个进程都有它自己的内存空间和系统资源。
- 线程:是进程中的单个顺序控制流,是一条执行路径
- 单线程:一个进程如果只有一条执行路径,则称为单线程程序
- 多线程:一个进程如果有多条执行路径,则称为多线程程序
- 线程调度
线程有两种调度模型
- 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
- 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多一些。
Java使用的是抢占式调度模型
多线程的实现方式
- 夺多线程实现的方案有两种
①继承Thread类
②实现Runnable接口 - 相比继承Thread类,实现Runnable接口的好处
①避免了Java单继承的局限性
②适合多个相同程序的代码处理同一资源的情况,把线程和程序的代码、数据有效分离,较好体现了面向对象的设计思想 - 方式一:继承Thread类
①定义一个类MyThread继承Thread
②在MyThread类中重写run()方法
③创建MyThread对象
④启动线程,调用start()方法,虚拟机会自动调用run()方法
- 为什么要重写run方法?
因为run()是用来封装被线程执行的代码。 - run()与start()的区别?
run:封装线程执行的代码,直接调用,相当于普通方法的调用。
start:启动线程;然后由JVM调用此线程的run方法。
- 实现Runnable接口
①定义一个类MyRunnable实现Runnable接口
②在MyRunnable类中重写run()方法
③创建MyRunnable类的对象
④创建Thread类的对象,把MyRunnable对象作为构造方法的参数
⑤启动线程
Thread类中设置和获取线程名称的方法
①void setName(String name):将此线程的名称改为等于参数name
②String getName():返回此线程的名称
③通过构造方法也可以设置线程名称。需要在自己创建的继承Thread的类中添加构造方法super()调用父类的构造方法
获取main()方法所在的线程名称
Thread类中的静态方法返回线程对象。
public static Thread currentThread():返回当前正在执行的线程对象的引用
Thread.currentThread().getName;
Thread类中设置和获取线程优先级的方法
- public final int getPriority():返回此线程的优先级
- public final void setPriority(int newPriority):更改此线程的优先级
①线程默认优先级为5;
②线程优先级的范围是1-10;
③线程优先级高仅仅表示线程获取的CPU时间片的几率高。
线程控制
方法名 | 说明 |
---|---|
static void sleep(long millis) | 使当前正在执行的线程停留(暂停执行)指定的毫秒数(static修饰,使用Thread.sleep(1000)调用) |
void join() | 等待这个线程死亡 |
void setDaemon(boolean on) | 将此线程标记为守护线程,当运行的线程都是守护线程时,java虚拟机将退出 |
线程生命周期
线程的生命周期.png数据安全问题
- 判断多线程程序是否会有数据安全问题的标准
①是否是多线程环境
②是否有共享数据
③是否有多条语句操作共享数据 - 如何让解决多线程安全问题
①基本思想:让程序没有安全问题的环境
②把多条语句操作共享数据的代码锁起来,让任意时刻只能有一个线程执行即可,可以使用同步代码块实现 -
同步代码块
①格式
synchronized(任意代码){
多条语句操作共享数据代码
}
②synchronized(任意对象):就相当于给代码加锁了,任意对象可以看成一把锁
public class SellTicket implements Runnable {
private int ticketCount = 100;
private Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (obj) {//不要在这里new一个对象,相当于给每个线程加了不同的锁,每个进程依然能执行下面的代码
if (ticketCount > 0) {
System.out.println(Thread.currentThread().getName() + "正在出售第" + ticketCount + "张电影票");
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticketCount--;
}
}
}
}
}
- 同步的好处和弊端
①好处:解决了多线程的数据安全问题
②弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很消耗资源的,无形中会降低程序的运行效率 -
同步方法
同步方法:就是把synchronized关键字加到方法上
①同步方法的锁对象是:this
同步静态方法的锁对象是:类名.class
网友评论