多线程和单例
1. 多线程
1.1 线程的生命周期
1.2 线程通信涉及到的方法
所有方法的都来自Object类,以下方法都是通过【锁对象调用】
void wait();
在哪一个线程代码中执行,哪一个线程进入阻塞状态。【开启锁对象】
static Thread currentThread();
void notify();
通过锁对象调用,唤醒通过当前锁对象限制的进入休眠状态的一个线程。【开启锁对象】
void notifyAll();
通过锁对象调用,唤醒通过当前锁对象限制的进入休眠状态的所有线程。【开启锁对象】
1.3 生产者消费者模型分析
1.4 生产者消费者代码实现
package com.qfedu.a_thread;
class Producer extends Thread {
Goods goods;
public Producer() {
}
public Producer(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
while (true) {
synchronized (goods) {
if (goods.shouldProduct) {
if (Math.random() > 0.5) {
goods.name = "柯尼塞格";
goods.price = 10.5F;
} else {
goods.name = "五菱之光";
goods.price = 500000000;
}
System.out.println("生产者生产了:" + goods.name + " 价格:" + goods.price);
goods.shouldProduct = false;
goods.notify();
} else {
System.out.println("生产者睡觉~~~");
try {
goods.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Customer extends Thread {
Goods goods;
public Customer() {
}
public Customer(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
while (true) {
synchronized (goods) {
if (!goods.shouldProduct) {
System.out.println("消费者购买了:" + goods.name + " 价格:" + goods.price);
goods.shouldProduct = true;
goods.notify();
} else {
System.out.println("消费者睡觉~~~");
try {
goods.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Goods {
String name;
float price;
boolean shouldProduct;
public Goods() {
}
public Goods(String name, float price, boolean shouldProduct) {
this.name = name;
this.price = price;
this.shouldProduct = shouldProduct;
}
}
public class Demo1 {
public static void main(String[] args) {
Goods goods = new Goods("柯尼塞格", 10.5F, true);
Producer producer = new Producer(goods);
Customer customer = new Customer(goods);
producer.start();
customer.start();
}
}
1.5 线程池
1.5.1 线程池概念
餐厅服务员
1. 一个餐厅有5个服务员
2. 每一个服务员执行了自己的任务,重新回到等待位置
3. 餐厅开门,服务员准备就绪,餐厅停止营业,服务员下班走人
多线程代码需求分析
1. 创建一个【线程池】,准备5个线程
2. 提供给线程任务(Runnable target) what will be run。执行目标,执行完毕。进入等待。【触发 ==> 提交任务,当前线程执行目标】
3. 程序开启,线程池准备,程序退出,线程池销毁
1.5.2 Java中线程池使用
面向百度编程~~~
class Executors 涉及到线程池方法
1、newCachedThreadPool:用来创建一个可以无限扩大的线程池,适用于负载较轻的场景,执行短期异步任务。(可以使得任务快速得到执行,因为任务时间执行短,可以很快结束,也不会造成cpu过度切换)
2、newFixedThreadPool:创建一个固定大小的线程池,因为采用无界的阻塞队列,所以实际线程数量永远不会变化,适用于负载较重的场景,对当前线程数量进行限制。(保证线程数可控,不会造成线程过多,导致系统负载更为严重)
3、newSingleThreadExecutor:创建一个单线程的线程池,适用于需要保证顺序执行各个任务。
4、newScheduledThreadPool:适用于执行延时或者周期性任务。