# 多线程概述
- 进程:正在运行的程序
- 系统进行资源分配粒调用的独立单位
- 每一个进程都有它自己的内存空间和系统资源
- 线程:进程中的单个顺序控制流,是一条执行路径
- 单线程:一条执行路径
- 多线程:多条执行路径
# 多线程的实现
# 继承 Thread 类
# 使用
重写 run()
方法,调用 start()
方法
run()
:封装线程执行的代码start()
:执行线程,jvm 虚拟机调用run()
方法
# 设置 / 获取线程名称
void setName(String name)
:改线程名String getName()
:返回线程名- 构造方法设置线程名称 -> 子类需要写带参构造方法
public static Thread currentThread()
:获取对当前正在执行的线程对象的引用Thread.currentThread().getName();
# 实现 Runnable 接口
# 使用
- 定义类实现 Runnable 接口,重写 run () 方法,并创建对象
- 创建 Thread 对象,让类的对象传入
Thread(Runnable target)
Thread(Runnable target, String name)
- 启动线程
# 优点
- 方便继承别的类
- 多个线程访问一个资源
# 线程优先级
# 线程调度
- 分时调度模型:线程轮流使用 CPU,平均分配 CPU 时间片
- 抢占式调度模型:优先让优先级高的线程使用 CPU,优先级相同的则随机分配
- Java 使抢占式调度模型,线程执行具有随机性
# 查询 / 设置优先级
public final int getPriority()
:返回此线程的优先级public final void setPriority()
:更改此线程的优先级- 最大 10
- 最小 1
- 默认 5
# 线程控制
static void sleep(long mullis)
:使当前正在执行的线程停留(暂停执行)指定的毫秒数void join()
:等待这个线程死亡 -> 使其线程独占void setDaemon(boolean on)
:标记为守护线程,当运行的线程都是守护线程时,Java 虚拟机将退出- boolean on:true 开启,false 关闭
- 不会立即退出
# 线程的声明周期
- 创建对象:
new()
- 有资格,没权利:
start()
- 有资格,有权利运行:抢占到 cpu 资源
- 阻塞:
sleep()
- 结束:
stop()
- 阻塞:
# 线程同步
# 数据安全问题
# 原因
- 多线程环境
- 有数据共享
- 有多余语句操作共享数据
# 解决问题
不允许多线程共同操作共享数据
# 同步代码块
synchronized (任意对象) { | |
多条语句操作共享数据的代码 | |
} |
synchronized(任意对象)
:任意对象就可以看成是一把锁 / 钥匙
# 同步方法
# 同步方法
- 格式:
修饰符 sychronozed 返回值类型 方法名(方法参数) {}
- 锁 / 钥匙:this
# 同步静态方法
- 格式:
修饰符 static sychnronized 返回值类型 方法名(方法参数){}
- 锁 / 钥匙:类名.class
# 线程安全类
- StringBuffer:线程安全的 StringBuilder
- Vector:线程安全的 ArrayList
- Hashtable:线程安全的 HashMap
- 返回线程安全的列表
// 定义 | |
static <T> List<T> sychronized (List<T> list); | |
// 实例 | |
List<Integer> list = Collections.synchronizedList(new ArrayList<>()); |
# Lock 锁
# 间接实例化
private Lock lock = new ReentrantLock;
# 获得锁
void lock()
# 关闭锁
void unlock()
# 生产者消费者模型
# 概述
生产者 -> 共享数据区域 <- 消费者
# Object 类的等待唤醒方法
void wati()
:当前线程等待void notify()
:唤醒正在等待对象监视器的单个线程void notifyAll()
:唤醒所有线程
# 使用注意
wait()
与notify()/notifyAll()
成对出现- 加入 boolean state 变量判断等待与唤醒
# 代码实现
public class Box { | |
private int milk; | |
private boolean state = false; | |
public synchronized void put(int milk) { | |
if(state){ | |
try { | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
this.milk = milk; | |
System.out.println("送" + this.milk + "瓶奶"); | |
state = true; | |
notifyAll(); | |
} | |
public synchronized void get() { | |
if(!state) { | |
try { | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
System.out.println("取" + this.milk + "瓶奶"); | |
state = false; | |
notifyAll(); | |
} | |
} |
public class Customer implements Runable { | |
private Box b; | |
public Customer(Box b) { | |
this.b = b; | |
} | |
@Override | |
public void run() { | |
while (true) { | |
b.get(); | |
} | |
} | |
} |
public class Producer implements Runable { | |
private Box b; | |
public Producer(Box b) { | |
this.b = b; | |
} | |
@Override | |
public void run () { | |
for(int i = 1; i <= 5; i++) { | |
b.put(i); | |
} | |
} | |
} |
public class BoxDemo { | |
public static void main(String[] args) { | |
Box b = new Box(); | |
Customer c = new Customer(b); | |
Producer p = new Producer(b); | |
Thread t1 = new Thread(c); | |
Thread t2 = new Thread(p); | |
t1.start(); | |
t2.start(); | |
} | |
} |