一、线程池
1.等待唤醒机制
1)线程间通信
*通信举例:对产品的状态进行判断
产品状态(无)-->消费者唤醒生产者线程-->消费者等待-->产品生产完-->修改产品状态为(有)
产品状态(有)-->生产者唤醒消费者进程-->生产者等待-->产品消耗完-->修改产品状态为(无)
2)等待唤醒机制--多线程之间的协作机制
*等待唤醒的方法
wait();notify();notifyAll;
*注意事项:
wait()和notify()必须由同一个锁对象调用
wait()和notify()必须放在同步代码块中使用
3)等待唤醒机制需求分析
*资源类:包子类
**设置包子的属性
**设置包子的状态true/false
*生产者类:线程类
**设置线程任务:生产包子
**包子状态true
包子铺调用wait方法进入等待状态
包子状态false
包子铺生产好包子
修改包子状态为true
用notify方法唤醒消费者线程
*消费者类:线程类
**设置线程任务:消耗包子
包子状态false
吃货线程调用wait方法进入等待状态
包子状态true
吃货吃包子
修改包子状态为false
唤醒包子铺做包子
问题:如果有多个顾客,包子铺每次只能生产一个包子,怎么让顾客轮流吃包子???在第三部分解答
2.线程池:降低系统消耗,便于线程管理
1)原理:创建List<Thread> threads
使用时:Thread t = threads.remove()
使用完毕:threads.add(t)
2)JDK1.5提供了类和方法,实现线程池
使用步骤
*ExecutorService threadPool= Executors.newFixedThreadPool :创建一个固定数量的可重用线程池
*创建一个类,实现Runnable接口,重写run方法,设置线程任务
*调用ExecutorService中方法submit,传递线程任务,开启线程,执行run方法
*调用ExecutorService中方法shutdown销毁线程池(不建议执行)
二、Lambda表达式
1.函数式编程思想:找一个函数来实现功能
面向对象的思想:找一个对象,调用这个对象,来完成功能
2.Lambda表达式的写法(代替匿名内部类)
1)Lambda表达式的使用情形-->将一个方法的重写内容传递给一个类
2)标准格式:
*(参数列表)->{重写的方法代码}
注:有返回值的方法在方法体中加入return xxx
*格式说明:
():接口中抽象方法的参数列表,没有参数则为空.有参数就写出参数
->:传递参数
{}:重写接口的抽象方法的方法体
3)简化格式:
*可省略的内容
(参数列表):括号中的数据类型,可以省略不写
(参数列表):括号中的参数,如果只有一个,那么类型和()都可以省略
{代码}:如果{}中代码只有一行,无论有无返回值,都可以省略{}和return和;
注意事项: {}、return和;要省略必须一起省略;
4)Lambda表达式的使用限制
只有函数式接口创建匿名内部实现类的时候才可以使用Lambda表达式
函数式接口:只有一个抽象方法的接口
三、探索分享:使用线程等待实现包子铺的多个顾客轮流吃包子
主要思想,将顾客加上编号,使用if语句判断是否为自己的号码,如果不是,就进入等待
另外使用continue语句跳出while循环来实现线程被唤醒后重新判断,而不是继续运行
1.创建包子类
package cn.itcast.demo01;
[Java] 纯文本查看 复制代码 public class BaoZi {
private String pi;
private String xian;
private boolean exit = false;
private int index = 0;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public BaoZi() {
}
public BaoZi(String pi, String xian, boolean exit) {
this.pi = pi;
this.xian = xian;
this.exit = exit;
}
public String getPi() {
return pi;
}
public void setPi(String pi) {
this.pi = pi;
}
public String getXian() {
return xian;
}
public void setXian(String xian) {
this.xian = xian;
}
public boolean isExit() {
return exit;
}
public void setExit(boolean exit) {
this.exit = exit;
}
}
2.创建包子铺线程类[Java] 纯文本查看 复制代码 package cn.itcast.demo01;
public class BaoZiPu implements Runnable {
private BaoZi bz;
private int number;
public BaoZiPu() {
}
public BaoZiPu(BaoZi bz,int number) {
this.bz = bz;
this.number = number;
}
public BaoZi getBz() {
return bz;
}
public void setBz(BaoZi bz) {
this.bz = bz;
}
@Override
public void run() {
int count = 0;
int index = 0;
while (true) {
synchronized (bz) {
//判断包子的状态是有还是没有,如果有,则进入等待
if (bz.isExit() == true) {
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
continue;
}
//如果包子的状态是没有,则做包子,做包子需要2秒
if (count % 2 == 0) {
bz.setPi("厚皮");
bz.setXian("盐馅");
} else {
bz.setPi("薄皮");
bz.setXian("牛肉馅");
}
count++;
bz.setIndex(index);
if(index< number - 1) index++;
else index = 0;
System.out.println("老板开始做" + bz.getPi() + bz.getXian() + "包子");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//包子做好了,改包子的状态为true
bz.setExit(true);
//唤醒顾客线程,吃包子
bz.notify();
System.out.println("1个" + bz.getPi() + bz.getXian() + "包子做好了,可以吃了!");
}
}
}
}
3.创建顾客类[Java] 纯文本查看 复制代码 package cn.itcast.demo01;
public class Customer implements Runnable {
private BaoZi bz;
private String name;
private int index;
public Customer() {
}
public Customer(String name, int index, BaoZi bz) {
this.bz = bz;
this.name = name;
this.index = index;
}
public BaoZi getBz() {
return bz;
}
public void setBz(BaoZi bz) {
this.bz = bz;
}
@Override
public void run() {
while (true) {
synchronized (bz) {
//查看包子的状态,如果包子没有,则进入等待,则唤醒老板做包子
if (bz.isExit() == false || bz.getIndex() !=index) {
try {
bz.notify();
bz.wait();//自己进入等待
} catch (InterruptedException e) {
e.printStackTrace();
}
continue;
}
//如果有包子,则吃
System.out.println(name + "正在吃" + bz.getPi() + bz.getXian() + "的包子");
//吃完了包子
bz.setExit(false);
System.out.println("吃完了,请老板继续做包子");
bz.notify();
System.out.println("=========================");
}
}
}
}
4.使用测试类测试:[Java] 纯文本查看 复制代码 package cn.itcast.demo01;
import java.util.LinkedList;
import java.util.List;
public class Test {
public static void main(String[] args) {
BaoZi bz = new BaoZi();
new Thread(new BaoZiPu(bz,5)).start();
//创建线程池
LinkedList<Thread> threads = new LinkedList<>(
List.of(new Thread(new Customer("小A", 0, bz)),
new Thread(new Customer("小B", 1, bz)),
new Thread(new Customer("小C", 2, bz)),
new Thread(new Customer("小D", 3, bz)),
new Thread(new Customer("小E", 4, bz))));
threads.removeFirst().start();
threads.removeFirst().start();
threads.removeFirst().start();
threads.removeFirst().start();
threads.removeFirst().start();
}
}
|
|