内容
Ⅰ进程与线程
Ⅱ线程安全
Ⅲ卖票系统demo
具体内容
Ⅰ进程与线程
1.(1)进程:正在运行的一个程序
系统会为这个进程分配独立的内存资源
(2)线程:具体执行任务的最小单位
一个进程最少拥有一个线程(主线程 运行起来就执行的线程)
线程之间是共享内存资源的(进程申请的)
线程之间可以通信(数据传递:多数为主线程和子线程)
2.进程与线程的关系图示
3.为什么不使用多进程而是使用多线程?
线程廉价,线程启动比较快,退出比较快,对系统资源的冲击也比较小,而且线程彼此分享了大部分核心对象(File Handle)的拥有权
使用多重进程,不可预期,且测试困难
4.为什么需要创建子线程
在主线程中存在有比较耗时的操作:下载视频 上传文件 数据处理
这些操作会阻塞主线程 后面的任务必须等这些任务执行完毕之后才能执行
为了不阻塞主线程,需要将耗时的任务放在子线程中去处理
5.创建一个子线程的方法
(1)定义一个类继承于Thread 实现run方法
join:让当前这个线程阻塞 等join的线程执行完毕再执行
setName:设置线程名称
getName:获取线程名称
currentThread:获取当前运行的线程对象
start:开启任务
(2)实现Runnable接口 实现run方法
a.创建任务 创建类实现Runnable接口
b.使用Thread 为这个任务分配线程
c.开启任务 start
(3)创建线程的同时,直接开启线程任务,不需要操作线程对象本身
(4)最简洁的方式 - 使用Lambda表达式
Ⅱ线程安全
1.什么是线程安全
指的是确保在多条线程访问的时候,我们的程序还能按照我们预期的行为去执行
2.线程的状态
NEW:新建 线程刚被创建好 至今尚未启动的线程处于这种状态
RUNNABLE:就绪状态,只要抢到时间片就可以随时运行这个线程,正在 Java 虚拟机中执行的线程处于这种状态
BLOCKED:阻塞状态 sleep wait
WAITING:等待 wait
TIMED_WAITING:限时等待一个正在限时等待另一个线程执行一个动作的线程处于这一状态
TERMINATED:终止,已退出的线程处于这种状态
3.如何实现线程安全
(1)使用synchronized
synchronized关键字,就是用来控制线程同步的,保证我们的线程在多线程环境下,不被多个线程同时执行,确保我们数据的完整性,使用方法一般是加在方法上
(2)使用Lock
4.同步锁中await、signal和signalAll的使用
Condition实例被绑定在一个Lock的对象上,使用Lock对象的方法newCondition()获取Condition的实例。Condition提供了下面三种方法,来协调不同线程的同步:
await():导致当前线程等待,直到其他线程调用该Condition的signal()或signalAll()方法唤醒该线程
signal():唤醒在此Lock对象上等待的单个线程
signalAll():唤醒在此Lock对象上等待的所有线程
Ⅲ卖票系统demo
public static void main(String[] args) {
Ticket ticketCQ = new Ticket("重庆");
Thread t1 = new Thread(ticketCQ);
t1.start();
Ticket ticketSH = new Ticket("上海");
Thread t2 = new Thread(ticketSH);
t2.start();
}
}
//用于卖票的任务
class Ticket implements Runnable {
//定义所有车票的数量
public static int num = 100;
String name;
public Ticket(String name) {
this.name = name;
}
static final Object obj = new Object();
//创建一个可重入的锁
static ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
//判断有没有票
//加锁
// synchronized (obj) {
lock.lock();
//需要同步的代码
if (num > 0) {
System.out.println(name + "出票:" + num);
num--;
// try {
// //当前线程等待
// obj.notify();
// obj.wait();
// } catch (InterruptedException e) {
// e.printStackTrace();
// } finally {
// //通知其他线程执行
//
// }
} else {
break;
}
//解锁
lock.unlock();
}
}