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