import java.util.Stack;
/*
* 多线程同步例子:当厨师线程开始执行put方法或者服务员开始get方法时,都必须先获取MediContainer对象的锁,
* 如果该锁被其他线程占用,另一个线程就只能在锁池中等待。这种锁机制使得厨师线程执行put方法的整个过程中
* ,服务员线程不会执行get方法,同样,在服务员线程在执行get方法的整个过程中,厨师线程不执行put方法。
*
* 注意,一个对象的wait方法和notify方法的调用应该放在同步代码块中,并且同步代码块采用这个对象的锁,
若果违背了这个规则,尽管在编译时不会检查这种错误,但在运行时会跑出IllegalMonitorException异常
*/
public class MutilThreadTest {
public static void main(String args[]){
MediContainer med=new MediContainer(5);
Thread thread[]={
new Cook(med),
new Cook(med),
new Waitress(med),
new Waitress(med),
new Waitress(med)
};
thread[0].setName("cooker1");
thread[1].setName("cooker2");
thread[2].setName("waitress1");
thread[3].setName("waitress2");
thread[4].setName("waitress3");
for(int i=0;i<thread.length;i++){//同时启动两个厨师线程,3个服务员线程
thread[i].start();
}
try {
Thread.sleep(2000);//运行2s后停止运行
med.setStop(true);
System.out.println("over");
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0;i<thread.length;i++){
thread[i].stop();
}
}
}
class MediContainer{//定义食物存储容器
public static Stack<Dish> slot=new Stack<Dish>();
public int slotCount;
public boolean stopflag=false;
public MediContainer(int slotcount){
this.slotCount=slotcount;
}
public void setStop(boolean flag){
this.stopflag=flag;
}
public boolean isStop(){
return this.stopflag;
}
public void put(Dish dish){//厨师放菜操作,当slot容器中炒菜数量为最大值时,该容器对象this.wait(),此时调用该方法的线程进入该对象的锁池
synchronized(this){
this.notifyAll();
//唤醒对象等待池中其余的等待线程,即JVM将该对象等待池中的对象都移到锁池中,在这里等待获得锁
//实际意义是,通知在等待池中的线程(准备从容器中取炒菜的服务员线程)准备到锁池中准备执行
while(slot.size()==this.slotCount){
try {
System.out.println(Thread.currentThread().getName()+"厨师等待放菜....");
this.wait();//此时,容器已满,厨师放弃对象锁和cpu进入该对象的等待池中
} catch (InterruptedException e) {
e.printStackTrace();
}
}
slot.push(dish);
System.out.println(Thread.currentThread().getName()+"完成一个炒菜,此时炒菜数量:"+slot.size());
}
}
public Dish get(){
synchronized(this){
this.notifyAll();
//唤醒对象等待池中其余的等待线程,即JVM将该对象等待池中的对象都移到锁池中,在这里等待获得锁;
//实际意义是,通知在等待池中的线程(准备往容器中放炒菜的厨师线程)准备到锁池中准备执行
while(slot.size()==0){
try{
System.out.println(Thread.currentThread().getName()+"服务员等待端菜....");
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"服务员取走一个炒菜,此时还剩炒菜数量:"+(slot.size()-1));
return slot.pop();
}
}
}
class Cook extends Thread{//定义一个厨师线程
private int id;
MediContainer med;
public static int number=1;
public Cook(MediContainer med){
this.id=number++;
this.med=med;
}
public void run(){
while(!med.isStop()){
Dish dish=new Dish(id);
med.put(dish);//该方法是同步方法,此时该对象必须获取med对象的同步锁,如果该锁被其他线程占用,则该对象进入med对象的锁池中阻塞
try {
Thread.sleep(10);//放弃cpu,将运行机会给别的线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Waitress extends Thread{
private int id;
MediContainer med;
public static int number=1;
public Waitress(MediContainer med){
this.id=number++;
this.med=med;
}
public void run(){
while(!med.isStop()){
Dish dish=med.get();//该方法是同步方法,此时该对象必须获取med对象的同步锁,如果该锁被其他线程占用,则该对象进入med对象的锁池中阻塞
try {
Thread.sleep(200);//放弃cpu,将运行机会给别的线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Dish{
public int id;
public Dish(int id){
this.id=id;
}
}
分享到:
相关推荐
a: 创建一个线程 b: 创建多个线程 c: 多线程访问同一资源 d: 经典线程同步互斥问题 e: 使用关键段解决子线程互斥问题 f: 利用事件实现线程同步问题 g: 利用互斥量来解决线程同步互斥问题 h: problem1 生产...
Java小程序:解决线程同步--生产者消费者问题,直观简单,容易理解,希望对初学者有帮助。
设计要求:(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者线程的标识符.(2)生产者和消费者各有两个以上.(3)多个生产者或多个消费者之间须有共享对缓冲区...
操作系统 用多线程同步方法解决生产者-消费者问题 课设报告
用多线程同步方法解决生产者-消费者问题(操作系统课设
利用线程间的通信主要是因为当多个线程同时对一个对象进行访问的时候,多个线程之间是一个协助的关系,举个例子就是今天要说的生产这和消费者模型。
1、设计目的:通过研究Linux的进程机制和信号量,实现生产者消费者问题的并发控制。 2、说明:有界缓冲区内设有20个存储单元,放入取出的产品设定为1-20个整数。 3、设计要求: 生产者和消费者进程的数目不固定,可...
操作系统实验 多线程实现生产者---消费者模型 华工版 绝对好用。。。。。。。
本代码是用JAVA实现的生产者与消费者的问题,线程间的同步与互斥功能
线程同步_生产者消费者问题 经典实现 线程同步_生产者消费者问题
1、设计目的:通过研究Linux的进程同步机制和信号量,实现生产者消费者问题的并发控制。 2、说明:有界缓冲区内设有26个存储单元,放入取出的产品设定为26个大写英文字母。 3、设计要求: 1) 生产者与消费者均有二个...
通过互斥量、事件来解决生产者和消费者的问题,主要涉及的内容有多线程的创建,事件的创建,互斥量的创建,线程的同步。主要的函数有:CreateThread,CreateEvent,CreateMutex,WaitForMultipleObjects等。
实用互斥量 解决 生产者-消费者 问题。并通过界面的方式展现出来(MFC).
用线程做一个生产者-消费者同步问题 其实我是想用线程做一个生产者-消费者同步问题,现在已经成功了,贴出来,大家请指证. 我想让线程thread1和thread2按顺序显示,于是加了个信号量mysem,并且在新建两个线程的两个...
用多线程同步方法解决生产者-消费者问题(操作系统课设)
多线程同步方法解决生产者-消费者问题 (Bounded - Buffer Problem) 内容:有界缓冲区内设有10个存储单元,放入/取出的数据项 设定为1~10这10个整形数。要求每个生产者和消费者对有界 缓冲区进行操作后,...
线程同步中的典型事例生产者消费者问题 方便理解线程的各方面内容
1、设计目的:通过研究Linux的进程同步机制和信号量,实现生产者消费者问题的并发控制。 2、说明:有界缓冲区内设有20个存储单元,放入取出的产品设定为20个100以内的随机整数。 3、设计要求: 1) 生产者与消费者均...