今天看见一个多线程问题,心里痒痒,就做了做,然后就有了这么一个小程序。
问题在这里:
http://www.iteye.com/problems/46763
有三方:厂家,电脑城,顾客
厂家2个,一个生产主板,一个生产显卡。
顾客有2个,他们各自不断购买主板和显卡。
电脑城有一个,卖显卡和主板。
货品类,方便调试:
public class Product {
private String name;
private int serial;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSerial() {
return serial;
}
public void setSerial(int serial) {
this.serial = serial;
}
}
货品供需管理类,多线程调度的核心:
import java.util.ArrayDeque;
public class StockManager {
private final Object producerLock = new Object();
private final Object consumerLock = new Object();
private final int MAX_SIZE = 10;
private final ArrayDeque<Product> queue = new ArrayDeque<Product>();
public void stock(Product p) throws InterruptedException {
synchronized (producerLock) {
if (queue.size() >= MAX_SIZE) {
producerLock.wait();
}
}
synchronized (queue) {
queue.add(p);
}
synchronized (consumerLock) {
consumerLock.notify();
}
}
public synchronized Product purchase() throws InterruptedException {
synchronized (consumerLock) {
if (queue.size() <= 0) {
consumerLock.wait();
}
}
Product product = null;
synchronized (queue) {
product = queue.remove();
}
synchronized (producerLock) {
producerLock.notify();
}
return product;
}
}
厂商类,可以生产产品,另有一个run,用于实现具体的生产过程,以调节测试时的供求关系:
import java.util.logging.Logger;
public class Producer implements Runnable{
private static final Logger log = Logger.getLogger(Producer.class.getName());
private String productName = null;
private int serial = 0;
private StockManager stockManager;
public void setProductName(String productName) {
this.productName = productName;
}
public void setStockManager(StockManager stockManager) {
this.stockManager = stockManager;
}
public Product produce() {
final Product p = new Product();
p.setName(productName);
p.setSerial(++serial);
return p;
}
@Override
public void run() {
try {
for( int i = 0; i < 20; i++) {
deliver();
}
Thread.sleep(30 * 1000);
while (true) {
deliver();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void deliver() throws InterruptedException {
final long s = System.currentTimeMillis();
final Product product = produce();
stockManager.stock(product);
final long time = System.currentTimeMillis() - s;
if (time > 10) {
log.info(product.getName() + ", No. " +
product.getSerial() + " took " +
time + " milli seconds to finish." );
}
}
}
客户类,比较简单,外加调试信息:
import java.util.logging.Logger;
public class Consumer implements Runnable {
private static final Logger log = Logger.getLogger(Consumer.class.getName());
private String name;
private StockManager[] stockManagers;
public void setName(String name) {
this.name = name;
}
public void setStockManagers(StockManager[] stockManagers) {
this.stockManagers = stockManagers;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
final double v = Math.random() * stockManagers.length;
final int k = (int) Math.floor(v);
try {
final long s = System.currentTimeMillis();
final Product product = stockManagers[k].purchase();
final long time = System.currentTimeMillis() - s;
String l = "";
if (time > 10) {
l += "after " + time + " milli seconds of waiting, ";
}
l += (name + " bought product " + product.getName()
+ ", serial No. " + product.getSerial());
log.info(l);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
程序入口,初始化上述各类,启动相应线程:
public class Mall {
public static void main(String[] args) {
final StockManager mb = new StockManager();
final Producer pmb = new Producer();
pmb.setProductName("Motherboard");
pmb.setStockManager(mb);
final StockManager vd = new StockManager();
final Producer pvd = new Producer();
pvd.setProductName("Video Card");
pvd.setStockManager(vd);
final StockManager[] stockManagers = new StockManager[2];
stockManagers[0] = mb;
stockManagers[1] = vd;
final Consumer c1 = new Consumer();
c1.setName("C1");
c1.setStockManagers(stockManagers);
final Consumer c2 = new Consumer();
c2.setName("C2");
c2.setStockManagers(stockManagers);
final Thread tc1 = new Thread(c1);
tc1.start();
final Thread tc2 = new Thread(c2);
tc2.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(pmb).start();
new Thread(pvd).start();
try {
tc1.join();
tc2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// kill system after consumer done shopping
System.exit(0);
}
}
感觉StockManager还是有些问题,但是又说不清楚。
分享到:
相关推荐
java多线程小程序实例 java多线程小程序实例
标题 "一个多线程下载程序" 描述了一个使用VC++编程语言实现的软件,该软件能够通过多线程技术加速文件的下载过程。多线程下载是现代互联网应用程序中常见的优化技术,尤其对于大文件下载,它能显著提高下载速度,...
多线程是操作系统中的一种机制,它允许一个进程内创建多个并发执行的线程。这些线程共享同一内存空间,可以并行执行不同的任务,如处理用户输入、网络通信、计算等。通过合理利用多核处理器资源,多线程可以显著提升...
本文将深入探讨在.NET框架中用于多线程同步的三个主要工具:Monitor、Mutex和EventWaitHandle,并结合提供的"五个多线程同步应用小程序",解释它们的应用场景和使用方法。 首先,我们来看Monitor类。Monitor是.NET...
标题中的“多线程 小球 运行程序(eclipse工程可导入)”表明这是一个与多线程编程相关的项目,可能是用Java语言实现的,因为Eclipse是Java开发的常用集成开发环境。这个程序可能设计了一个模拟小球运动的场景,通过多...
在“java多线程控制小球程序”这个项目中,我们看到一个具体的应用场景:多个小球在一个框内不断弹跳,并且这些小球可能在不同的时间发射。这样的设计可以模拟现实世界的物理现象,例如弹珠台或者粒子碰撞,同时也是...
在这个“一个多线程同步读写的小程序”中,我们看到开发者尝试通过创建读线程和写线程来同时进行数据的读取和写入,以优化程序的执行流程。 首先,让我们深入理解多线程的概念。线程是操作系统分配处理器时间的基本...
本文将以"VC++介绍一个多线程下载程序"为主题,深入探讨多线程技术及其在VC++环境中的应用。 首先,多线程是指在一个进程中创建多个执行线程,每个线程可以并发执行不同的任务。在下载程序中,多线程技术可以显著...
回到“c#.net写的调用多线程小程序”的主题,这个小程序可能利用了以上的一种或多种技术,来实现同时启动多个应用程序。例如,它可能为每个要启动的应用程序创建一个`Thread`,并在每个线程中调用`Process.Start`...
自己编写的简单的多线程小程序,一共四个线程,分别执行(+1,-1),(+2,-2),(+3,-3),(+4,-4),无同步。每次输入非零数,可以出现以一百为基数的结果。每次结果未必相同。如果有同步,会得100 。 可以体验多...
"自制MFC小程序用了多线程"这个标题表明,这个程序利用了MFC库来创建一个具有多线程功能的小应用程序。下面我们将详细讨论多线程以及在MFC中实现多线程的相关知识点。 1. **多线程概念**: 多线程是在单个进程中...
在这个名为"java多线程小汽车运行程序"的项目中,我们可以看到一个利用Java实现的多线程应用程序,可能是模拟汽车运行或者交通系统的一个小型示例。 在Java中,创建线程主要有两种方式:继承`Thread`类和实现`...
本资源“Win32多线程程序设计全部代码”提供了完整的源代码示例,帮助开发者深入理解和实践如何在Win32环境下创建和管理多线程应用程序。 一、Win32 API与多线程 Win32 API是Microsoft Windows操作系统的核心接口,...
多线程编程是指在一个程序中同时运行多个线程,以提高程序的执行效率和响应速度。在 Windows 平台上,多线程编程通常使用 WINAPI 提供的线程控制函数来实现。 在多线程程序中,需要使用线程建立函数 CreateThread ...
多线程是指在一个进程中同时运行多个独立的执行线程。每个线程都有自己的程序计数器、栈和局部变量,它们共享进程的全局变量和系统资源。通过多线程,程序可以同时执行多个任务,如数据读取、处理和用户交互,从而...
在深入探索 POSIX 多线程程序设计之前,我们需要了解POSIX(可移植操作系统接口)是一个定义一系列UNIX系统服务的接口标准,这些服务包括文件处理、进程控制、信号处理、定时器、多线程等,POSIX标准让编写的应用...
在多线程下载程序中,每个线程负责下载文件的一个部分。以下是一些关键知识点: 1. **线程创建与管理**:Leo2005使用了操作系统提供的API或编程语言的库函数(如Java的Thread类或C++的std::thread)来创建和管理...
本教程通过一个简单的小例子来讲解如何在VB 6.0中实现多线程。 首先,我们要了解线程是什么。线程是程序中的执行流程,每个线程负责一部分任务,这样可以使得程序在等待某个任务完成时,其他任务仍然能够继续执行。...
在本“关于多线程的C#小程序”中,我们将深入探讨如何在C#环境中创建和管理多线程,以及如何进行有效的异常处理。 一、线程基础 线程是操作系统分配CPU时间的基本单位。在单核处理器中,一个进程只有一个线程,但在...
【口味王小程序养号多线程版】是一个针对微信小程序"口味王"的自动化运营工具,主要用于提升账号活跃度和优化用户体验。这个程序利用多线程技术,可以同时管理多个账号,实现批量操作,提高效率。在IT领域,多线程...