网站 建设ppt模板更改wordpress主题语言
2026/3/25 15:58:33 网站建设 项目流程
网站 建设ppt模板,更改wordpress主题语言,网站模板展示,怎么重新设置wordpress一、线程间通信的核心场景最典型的场景是生产者 - 消费者模型#xff1a;生产者线程#xff1a;生产数据#xff08;往共享容器里放数据#xff09;消费者线程#xff1a;消费数据#xff08;从共享容器里取数据#xff09;通信需求#xff1a;容器满时生产者等待…一、线程间通信的核心场景最典型的场景是生产者 - 消费者模型生产者线程生产数据往共享容器里放数据消费者线程消费数据从共享容器里取数据通信需求容器满时生产者等待容器空时消费者等待生产 / 消费后唤醒对方。二、Java 实现线程通信的 3 种核心方式方式 1使用 Object 类的 wait ()/notify ()/notifyAll ()基础经典这是基于对象监视器锁的通信方式必须在synchronized代码块 / 方法中使用wait()让当前线程释放锁并进入等待状态直到被唤醒。notify()唤醒等待该对象锁的一个线程随机。notifyAll()唤醒等待该对象锁的所有线程推荐避免线程永久等待。完整示例生产者 - 消费者java运行// 共享资源仓库最多存1个产品 class Warehouse { private int product 0; // 产品数量 // 生产产品生产者调用 public synchronized void produce() { // 仓库已满生产者等待 while (product 1) { // 用while而非if防止虚假唤醒 try { wait(); // 释放锁进入等待 } catch (InterruptedException e) { e.printStackTrace(); } } // 生产产品 product; System.out.println(Thread.currentThread().getName() 生产了产品当前库存 product); notifyAll(); // 唤醒消费者 } // 消费产品消费者调用 public synchronized void consume() { // 仓库为空消费者等待 while (product 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 消费产品 product--; System.out.println(Thread.currentThread().getName() 消费了产品当前库存 product); notifyAll(); // 唤醒生产者 } } // 生产者线程 class Producer implements Runnable { private Warehouse warehouse; public Producer(Warehouse warehouse) { this.warehouse warehouse; } Override public void run() { // 循环生产5次 for (int i 0; i 5; i) { warehouse.produce(); try { Thread.sleep(500); // 模拟生产耗时 } catch (InterruptedException e) { e.printStackTrace(); } } } } // 消费者线程 class Consumer implements Runnable { private Warehouse warehouse; public Consumer(Warehouse warehouse) { this.warehouse warehouse; } Override public void run() { // 循环消费5次 for (int i 0; i 5; i) { warehouse.consume(); try { Thread.sleep(800); // 模拟消费耗时 } catch (InterruptedException e) { e.printStackTrace(); } } } } // 测试类 public class WaitNotifyDemo { public static void main(String[] args) { Warehouse warehouse new Warehouse(); // 启动生产者和消费者线程 new Thread(new Producer(warehouse), 生产者1).start(); new Thread(new Consumer(warehouse), 消费者1).start(); } }关键解释wait()必须在synchronized块中调用因为调用前需要先获取对象锁调用后会释放锁这是和sleep()的核心区别sleep()不会释放锁。用while判断条件而非if防止 “虚假唤醒”线程被唤醒后条件可能已经不满足需要重新检查。notifyAll()比notify()更安全避免只唤醒同类线程比如生产者唤醒生产者导致死锁。方式 2使用 Condition 接口JUC 包更灵活Condition是 Java 并发包java.util.concurrent提供的增强版等待 / 唤醒机制基于Lock锁实现相比wait()/notify()更灵活可以创建多个 Condition实现精准唤醒。完整示例java运行import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; // 共享资源仓库 class Warehouse2 { private int product 0; private final Lock lock new ReentrantLock(); // 可重入锁 private final Condition producerCondition lock.newCondition(); // 生产者条件 private final Condition consumerCondition lock.newCondition(); // 消费者条件 // 生产产品 public void produce() { lock.lock(); // 获取锁 try { while (product 1) { producerCondition.await(); // 生产者等待替代wait() } product; System.out.println(Thread.currentThread().getName() 生产了产品当前库存 product); consumerCondition.signal(); // 精准唤醒消费者替代notify() } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); // 释放锁必须在finally中防止异常导致锁不释放 } } // 消费产品 public void consume() { lock.lock(); try { while (product 0) { consumerCondition.await(); // 消费者等待 } product--; System.out.println(Thread.currentThread().getName() 消费了产品当前库存 product); producerCondition.signal(); // 精准唤醒生产者 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } // 测试类 public class ConditionDemo { public static void main(String[] args) { Warehouse2 warehouse new Warehouse2(); new Thread(() - { for (int i 0; i 5; i) { warehouse.produce(); try { Thread.sleep(500); } catch (InterruptedException e) {} } }, 生产者1).start(); new Thread(() - { for (int i 0; i 5; i) { warehouse.consume(); try { Thread.sleep(800); } catch (InterruptedException e) {} } }, 消费者1).start(); } }核心优势可以创建多个Condition对象实现 “精准唤醒”比如只唤醒生产者 / 消费者而notify()是随机唤醒。Lock锁的获取和释放更灵活可以在非代码块中使用且支持尝试获取锁tryLock()。方式 3使用 BlockingQueue阻塞队列最高效BlockingQueue是 JUC 包提供的阻塞队列内置了线程通信逻辑无需手动写 wait/notify是生产环境中最推荐的方式。核心特性队列满时入队操作put()会阻塞生产者线程。队列空时出队操作take()会阻塞消费者线程。完整示例java运行import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; // 测试类无需自定义仓库直接用BlockingQueue public class BlockingQueueDemo { // 创建容量为1的阻塞队列模拟仓库 private static final BlockingQueueInteger queue new ArrayBlockingQueue(1); public static void main(String[] args) { // 生产者线程往队列里放数据 new Thread(() - { for (int i 1; i 5; i) { try { queue.put(i); // 队列满时阻塞 System.out.println(Thread.currentThread().getName() 生产了产品 i 队列大小 queue.size()); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }, 生产者1).start(); // 消费者线程从队列里取数据 new Thread(() - { for (int i 1; i 5; i) { try { Integer product queue.take(); // 队列空时阻塞 System.out.println(Thread.currentThread().getName() 消费了产品 product 队列大小 queue.size()); Thread.sleep(800); } catch (InterruptedException e) { e.printStackTrace(); } } }, 消费者1).start(); } }输出效果plaintext生产者1 生产了产品1队列大小1 消费者1 消费了产品1队列大小0 生产者1 生产了产品2队列大小1 消费者1 消费了产品2队列大小0 ...生产者和消费者交替执行核心优势无需手动处理锁和等待 / 唤醒代码极简不易出错。支持多种队列类型ArrayBlockingQueue数组实现、LinkedBlockingQueue链表实现、SynchronousQueue无容量队列等。三、核心方法对比方式核心 API优点缺点wait()/notify()Object 类方法基础经典无需额外依赖只能随机唤醒需手动处理锁易出错ConditionLockCondition精准唤醒锁更灵活代码稍复杂需手动释放锁BlockingQueueput()/take()极简高效生产环境首选依赖 JUC 包灵活性稍低适合标准生产消费场景总结线程间通信的核心是共享资源 等待 / 唤醒目的是让线程协同工作而非抢占资源。入门学习用wait()/notify()理解原理进阶用Condition实现精准控制生产环境优先用BlockingQueue极简且不易出错。关键注意点wait()会释放锁sleep()不会必须在锁保护的代码块中使用等待 / 唤醒方法用while判断条件防止虚假唤醒。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询