当前位置: 首页 > news >正文

线程协作

生产者消费者模式

这是一个线程同步问题,生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件.

  • 对于生产者,没有生产产品之前,要通知消费者等待.而生产了产品之后,又需要马上通知消费者消费
  • 对于消费者,在消费之后,要通知生产者已经结束消费,需要生产新的产品以供消费,
  • 在生产者消费者问题中,仅有synchronized是不够的
    • synchronized 可阻止并发更新同一个共享资源,实现了同步
    • synchronized不能用来实现不同线程之间的消息传递(通信)

Java提供了几个方法解决线程之间的通信问题

方法名 作用
wait() 表示线程一直等待,直到其他线程通知,与sleep不同会释放锁
wait(long timeout) 指定等待的毫秒数
notify() 唤醒一个处于等待状态的线程
notifyAII() 唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度

管程法

生产者消费者模型利用缓冲区解决

public class TestPC {public static void main(String[] args) {SynContainer s =  new SynContainer();new Producer(s).start();new Consumer(s).start();}
}class Producer extends Thread {SynContainer container;public Producer(SynContainer container) {this.container = container;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {container.addChicken(new Chicken(i));System.out.println("生产了"+i+"只鸡");}}
}class Consumer extends Thread {SynContainer container;public Consumer(SynContainer container) {this.container = container;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("消费了"+container.removeChicken().id+"只鸡");}}
}class Chicken {int id;Chicken(int id) {this.id = id;}
}class SynContainer {// 制定容器大小Chicken[] chickens = new Chicken[10];// 计数器int count = 0;// 生产者放入产品public synchronized void addChicken(Chicken chicken)  {while (count == chickens.length) {// 通知消费者消费,生产等待try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}chickens[count++] = chicken;// 通知消费this.notifyAll();}public synchronized Chicken removeChicken() {while (count == 0) {// 等待生产try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}Chicken chicken = chickens[--count];// 通知生产this.notifyAll();return chicken;}}

在wait()的使用场景中,必须用while循环包裹条件判断,而非if。这是多线程编程的经典规范,目的是:
应对虚假唤醒,确保线程不会在条件不满足时错误执行;
处理多线程竞争下,唤醒后条件已失效的情况,保证逻辑正确性。

信号灯法

// 信号灯法,标志位解决
public class TestPC2 {public static void main(String[] args) {TV tv = new TV();new Actor(tv).start();new Audience(tv).start();}
}// 生产者 -> 演员
class Actor extends Thread {TV tv;Actor(TV tv) {this.tv = tv;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {if (i % 2 == 0) {this.tv.play("java...");} else {this.tv.play("golang... ");}}}}
// 消费者 -> 观众
class Audience extends Thread {TV tv;Audience(TV tv) {this.tv = tv;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {this.tv.watch();}}
}
// 产品 -> 节目
class TV {// 拍电影 观众等, 看电影 演员等String voice;boolean flag = true;    // true -> 没有电影// 表演public synchronized void play(String voice) {while (!flag) {  // 注意:这里是!flag,因为flag=false表示已有节目,需等待消费try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("playing " + voice);// 通知观看this.voice = voice;this.flag = false;this.notifyAll();   // 锁在方法或代码块执行执行完后才释放,所以通知也可以放在前面}// 观看public synchronized void watch() {while (this.flag) {try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}// 通知表演System.out.println("watching " + this.voice);this.flag = true;this.notifyAll();}
}

线程池

  • 背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
  • 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实现重复利用。类似生活中的公共交通工具。
  • 好处:
    • 提高响应速度 (减少了创建新线程的时间)
    • 降低资源消耗(重复利用线程池中线程,不需要每次都创建)便于线程管理(..)
      • corePoolSize:核心池的大小maximumPoolSize:最大线程数
      • keepAliveTime:线程没有任务时最多保持多长时间后会终止
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TestPool {public static void main(String[] args) {// 创建线程池,制定参数大小ExecutorService pool = Executors.newFixedThreadPool(10);// 执行pool.execute(new myThread());pool.execute(new myThread());pool.execute(new myThread());pool.execute(new myThread());pool.execute(new myThread());// 关闭pool.shutdown();}
}class myThread extends Thread {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}
}
http://www.gsyq.cn/news/38650.html

相关文章:

  • 关于 Adobe Flash Player,这些重要信息你需要知道!
  • 2025年11月色素椒种子厂家前十排名:江苏恒润领跑市场
  • Paint.net中处理文本的缺点
  • Calico从VXLAN模式切换到IPIP模式
  • 【GitHub每日速递 20251103】Claude Cookbooks:一站式掌握Claude开发秘籍,解锁AI无限可能!
  • 2025年11月顶尖汽车水泵轴承品牌/厂家推荐:顶尖选择与行业洞察
  • 2025年11月国内烙馍机厂家推荐前十排行榜
  • 2025年11月圆锥滚子轴承厂家推荐榜:探索行业领先徐州优力同创的制造工艺与创新解决方案
  • 中电金信:喜获2024年度金融科技发展奖三等奖
  • 2025年11月行业水泵轴承实力厂家榜单:领军企业徐州优力同创与技术革新解析
  • 2025年度中国专业机打鲜奶品牌排名:机打清甜可口鲜奶与机打优质鲜奶服务商权威测评
  • Gitee:本土化项目管理工具的崛起与全球化布局
  • 2025年二手二效蒸发器定制厂家权威推荐榜单:二手降膜蒸发器/二手单效蒸发器/二手四效蒸发器源头厂家精选
  • 综合孔径微波辐射成像仿真程序实现(MATLAB)
  • 2025 最新外延片实力厂家口碑排行榜:年销 5.5 万片企业与定制服务能力全景对比及优质品牌最新推荐 MOSFET外延片/射频器件外延片/硅外延片公司推荐
  • 条件运算符
  • 2025年10月机器人线束生产工厂/厂家前十推荐榜单:东莞众晟强电子位居榜首
  • centos部署 KVM 虚拟化平台(保姆级)
  • 2025年市面上候车亭厂家推荐榜:探索行业领先的解决方案与创新技术
  • 2025年度中国工业制冷设备品牌排名:东洋制冷机靠不靠谱
  • 2025年油雾净化设备制造商:中国五大精密油雾净化设备靠谱供应商权威测评与深度解析
  • 2025年冷鲜肉切片机制造企业权威推荐榜单:牛肉切片机/连续式鲜肉切片机/鲜肉切片机源头厂家精选
  • 【科普】数据基础设施“三统一”是什么?
  • Smartproxy提取指南——JSON-first 架构与参数化最佳实践 - Smart
  • [PaperReading] GME: Improving Universal Multimodal Retrieval by Multimodal LLMs
  • 2025年11月市场地位认证机构排名榜:服务维度与行业口碑全面解析
  • MATLAB2025b安装教程
  • Comparable接口
  • 软件授权安全:如何筑牢防护壁垒
  • Java 时间日期类笔记