java多线程之生存者与消费者(Java编程思想)

1.Restaurant


package Produce;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class Meal {

private final int orderNum;

public Meal(int orderNum) {
this.orderNum = orderNum;
}

@Override
public String toString() {
return "Meal " + orderNum;
}
}

class WaitPerson implements Runnable {
private Restaurant restaurant;

public WaitPerson(Restaurant r) {
restaurant = r;
}

@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (restaurant.meal == null)
wait(); // 等待chef生产meal
}
System.out.println("Waitperson got " + restaurant.meal);
synchronized (restaurant.chef) {
restaurant.meal = null;
restaurant.chef.notifyAll();// 通知chef继续生产
}
}
} catch (InterruptedException e) {
System.out.println("WaitPerson interrupted");
}
}
}

class Chef implements Runnable {

private Restaurant restaurant;
private int count = 0;

public Chef(Restaurant r) {
restaurant = r;
}

@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (restaurant.meal != null)
wait();// 等待meal被拿走
}
if (++count == 10) {
System.out.println("Out of food,closing");
restaurant.exec.shutdownNow();//向每个线程发送Interrupt
return;//如果没有直接return 将多执行了下面的 Order up ,所以一般情况下都要直接return
}

System.out.println("Order up! ");
synchronized (restaurant.waitPerson) {
// 对notifyAll()的调用必须先获得waitPerson的锁
restaurant.meal = new Meal(count);
restaurant.waitPerson.notifyAll();
}
TimeUnit.MILLISECONDS.sleep(500);//休眠一下是为了给shutdownNow留出时间
}
} catch (InterruptedException e) {
System.out.println("Chef interrupted");
}
}
}

public class Restaurant {
Meal meal;
ExecutorService exec = Executors.newCachedThreadPool();
WaitPerson waitPerson = new WaitPerson(this);
Chef chef = new Chef(this);

public Restaurant() {
exec.execute(chef);
exec.execute(waitPerson);
}

public static void main(String[] args) {
new Restaurant();
}
}

2.使用java.util.concurrent.locks.Condition进行同步操作

Lock和Condition对象只有在更加困难的多线程问题中才是必需的。


package Produce;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Car {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean waxOn = false;

public void waxed() {
lock.lock();
try {
waxOn = true;// Ready to buff
condition.signalAll();
} finally {
lock.unlock();
}
}

public void buffed() {
lock.lock();
try {
waxOn = false;// Ready for another coat of wax
condition.signalAll();
} finally {
lock.unlock();
}
}

public void waitForWaxing() throws InterruptedException {
lock.lock();
try {
while (waxOn == false)
condition.await();
} finally {
lock.unlock();
}
}

public void waitForBuffing() throws InterruptedException {
lock.lock();
try {
while (waxOn == true)
condition.await();
} finally {
lock.unlock();
}
}
}

class WaxOn implements Runnable {
private Car car;

public WaxOn(Car c) {
car = c;
}

@Override
public void run() {
try {
while (!Thread.interrupted())
// while (true) //与使用这行效果一样
{
System.out.println("Wax On!");
TimeUnit.MILLISECONDS.sleep(200);
car.waxed();
car.waitForBuffing();
}
} catch (InterruptedException e) {
System.out.println("Exiting via interrupt");
}
System.out.println("Ending Wax On task");
}
}

class WaxOff implements Runnable {
private Car car;

public WaxOff(Car c) {
car = c;
}

@Override
public void run() {
try {
while (!Thread.interrupted())
// while (true)

{
car.waitForWaxing();
System.out.println("Wax Off!");
TimeUnit.MILLISECONDS.sleep(200);
car.buffed();
}
} catch (InterruptedException e) {
System.out.println("Exiting via interrupt");
}
System.out.println("Ending Wax Off task");
}
}

public class WaxOMatic2 {
public static void main(String[] args) throws InterruptedException {
Car car = new Car();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new WaxOff(car));
exec.execute(new WaxOn(car));
TimeUnit.SECONDS.sleep(5);
exec.shutdownNow();
}
}

java多线程之生存者与消费者(Java编程思想)

时间: 2024-11-02 23:23:51

java多线程之生存者与消费者(Java编程思想)的相关文章

多线程中的生产者消费者Java源代码(带注释)

同步解决了线程中数据存取不一致的问题,而Object类中的等待与唤醒方法解决了重复存取的问题 以下的生产者消费者Java源代码例子,很好的说明了这一点. 其中包括Info类.Producter类.Consumer类.Test类. <1> Info类如下: 1 package per.producterconsumer; 2 3 public class Info { 4 5 private boolean flag = true; 6 /* 7 * flag=true 表示此时可以生产,但不能

Java 多线程 简单实例 (消费者与生成者)的关系

PS::线程这套东西在PHP里完全是不存在的概念,有待进一步的学习: PS::这个实例是根据书本上的知识进行扩展的,理解程度50%左右吧! 1.定义生产消费环境 package second; public class Queue { int value = 0; boolean isEmpty = true; /** * 生产者 * @param v */ public synchronized void put(int v){ if(!isEmpty){//如果存在数据没有被消费 try{

Java多线程基础(四)Java传统线程同步通信技术

Java多线程基础(四)Java传统线程同步通信技术 编写代码实现以下功能 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程又循环100次,如此循环50次. 分析 1)子线程循环10次与主线程循环100次必须是互斥的执行,不能出现交叉,下面代码中通过synchronized关键字实现此要求: 2)子线程与主线程必须交替出现,可以通过线程同步通信技术实现,下面代码中通过bShouldSub变量实现此要求: 其他需要注意的地方 1)其中business变量必须声

Java多线程学习笔记--生产消费者模式

实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前水平只能膜拜,本次只能算学习笔记,为了巩固自己对Java多线程常规知识点的理解,路过大神还望能指导指导.下面一段代码是最常规的生产者消费者的例子: package com.zhanglei.demo; import java.util.ArrayList; import java.util.List

java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样,先定义一个缓冲区: public class ValueObject { public static String value = ""; } 换种写法,生产和消费方法放在一个类里面: public class ThreadDomain41 extends ReentrantLock {

Java多线程的生产者与消费者模型,线程间的通信

java多线程中的生产者与消费者模式:首先有一个阻塞队列,生产者将生产的东西放到队列里,消费者再从队列中取.当队列中的东西数量达到其容量就发生阻塞. import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import jav

Java多线程:Linux多路复用,Java NIO与Netty简述

JVM的多路复用器实现原理 Linux 2.5以前:select/poll Linux 2.6以后: epoll Windows: IOCP Free BSD, OS X: kqueue 下面仅讲解Linux的多路复用. Linux中的IO Linux的IO将所有外部设备都看作文件来操作,与外部设备的操作都可以看做文件操作,其读写都使用内核提供的系统调用,内核会返回一个文件描述符(fd, file descriptor),例如socket读写使用socketfd.描述符是一个索引,指向内核中一个

java多线程--“朴素版”生产者消费者问题

1. 生产/消费者模型 生产/消费者问题是个非常典型的多线程问题,涉及到的对象包括"生产者"."消费者"."仓库"和"产品".他们之间的关系如下: (01) 生产者仅仅在仓储未满时候生产,仓满则停止生产. (02) 消费者仅仅在仓储有产品时候才能消费,仓空则等待. (03) 当消费者发现仓储没产品可消费时候会通知生产者生产. (04) 生产者在生产出可消费产品时候,应该通知等待的消费者去消费. 2. 生产/消费者实现 下面通过

java多线程实现生产者与消费者---经典问题

前几天老师领着学习了一下单线程和多线程的题目. 这里是操作系统中非常经典的题目,生产者和消费者的题,这里涉及的是仓库, 只有一个人(生产者或消费者)进入,另一个人只有等待. 这里的重点是关于传值的问题.一定要保持一致,不然,对于存和取 的对象,就可能出现多个. //========================================================================// 仓库类 //====================================