等待唤醒机制代码实现_吃货类&测试类与线程池的概念和原理
消费者(吃货)类:是一个线程类,可以继承Thread
设置线程任务(run):吃包子
对包子的状态进行判断
false:没有包子
吃货线程调用wait方法进入等待状态
true:有包子
吃货吃包子
吃货吃完包子
修改包子的状态为false没有
吃货唤醒包子铺线程
package com.Thread.WaitAndNotify; /* 消费者(吃货)类:是一个线程类,可以继承Thread 设置线程任务(run):吃包子 对包子的状态进行判断 false:没有包子 吃货线程调用wait方法进入等待状态 true:有包子 吃货吃包子 吃货吃完包子 修改包子的状态为false没有 吃货唤醒包子铺线程 */ public class ChiHuo extends Thread{ //1.需要在成员位置创建一个包子变量 private BaoZi bz ; //2.使用带参数构造方法,为这个包子变量赋值 public ChiHuo(BaoZi bz) { this.bz = bz; } @Override public void run() { //使用死循环让包子一直吃包子 while (true){ //必须同时同步技术保证两个线程只能一个在执行 synchronized (bz){ //对包子的状态进行判断 if (bz.flag == false){ try { //吃货线程调用wait方法进入等待状态 bz.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //被唤醒之后执行的代码吃货吃包子 System.out.println("吃货正在吃:"+bz.pi+bz.xian+"包子"); //吃货吃完包子 //修改包子的状态为false没有 bz.flag = false; //吃货唤醒包子铺线程,生产包子 bz.notify(); System.out.println("吃货已经把:"+bz.pi+bz.xian+"包子吃完了,包子铺开始生产"); System.out.println("==================================="); } } } }
测试类:
包含main方法,程序执行的入口,启动程序
创建包子对象;创建包子铺线程,开启,创建吃货线程开启
package Synchronized_demo.Synchroned_Demo01; /* 测试类: 包含main方法,程序执行的入口,启动程序 创建包子对象;创建包子铺线程,开启,创建吃货线程,开启 */ public class Demo { public static void main(String[] args) { //创建包子对象 BaoZi bz = new BaoZi(); //创建包子铺线程,开启,生产包子 new BaoZiPu(bz).start(); //创建吃货线程,开启,吃包子 new ChiHuo(bz).start(); } }
线程池的概念和原理
我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?在Java中可以通过线程池来达到这样的效果。今天我们就来详细讲解一下Java的线程池。
线程池概念
线程池
其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
由于线程池中有很多操作都是与优化资源相关的,我们在这里就不多赘述。我们通过一张图来了解线程池的工作原理: