您的位置:首页 > 编程语言 > Java开发

Java 线程同步问题 生产者-消费者 算法实现 -Java学习笔记(29)

2007-07-19 15:20 1136 查看
我们晦涩的操作系统课本也讲过 生产者-消费者问题,不过是由Pascal写的用来解决 进程 同步的,不幸的是我并没学过Pascal。考试时大家都是用C语言写的,但是我极其怀疑这些应试程序段能不能拿到项目中应用。
课本上的算法是有信号量机制实现的(不要问我什么是信号量,课本上没讲)。声明一个int变量mutex(信号量),调用wait() signal()方法 。
wait(mutex); // if(mutex==0) { 阻塞当前进程; } else ( mutex--; }
signal(mutex); // mutex++; 唤醒wait进程

Java中似乎没有类似的方法,java中线程同步是由Object的方法wait() notify() / notifyAll() 实现的。这些方法必须在同步块(Critical Section 关键字synchronized)中。
我们知道synchronized (Object o) 是拿走对象o所拥有的唯一的钥匙(具体见我的另外一篇博客http://blog.csdn.net/nyzhl/archive/2007/05/19/1617014.aspx),
而o.wait()的作用就是阻塞当前线程并且释放对象o的钥匙
o.notify()/notifyAll()的作用是唤醒对象o wait阻塞的线程,重新竞争o的钥匙。

Thead.sleep()也是阻塞当前线程,但不释放钥匙

下面是我的程序源代码,3个生产者Alice,Bob,Lucy他们向只能放一个产品的容器里放产品 2个消费者James,Charlie。他们从容器里拿产品




/**//* 消费者生产者线程演示


* Coding by ZhaoHongliang.


**/




public class ProducerConsumer ...{




public static void main(String[] args) ...{


Container container = new Container();


Producer Alice = new Producer("Alice",container);


Thread produceThread1 = new Thread(Alice);


produceThread1.start();


Producer Bob = new Producer("Bob",container);


Thread produceThread2 = new Thread(Bob);


produceThread2.start();


Producer Lucy = new Producer("Lucy",container);


Thread produceThread3 = new Thread(Lucy);


produceThread3.start();


Consumer James = new Consumer("James",container);


Thread consumeThread1 = new Thread(James);


consumeThread1.start();


Consumer Charlie = new Consumer("Charlie",container);


Thread consumeThread2 = new Thread(Charlie);


consumeThread2.start();


}


}




/**//* 生产者 */




class Producer implements Runnable ...{


private String name;


private Container container = null;


//Constructor




public Producer(String producerName,Container container) ...{


this.name = producerName;


this.container = container;


}


//Override abstract methoed of Interface Runnable.




public void run() ...{




while(true) ...{




synchronized(this.container) ...{




while(!this.container.isEmpty()) ...{




try ...{


this.container.wait();


}




catch (InterruptedException e) ...{


e.printStackTrace();


}


}


Product pushedProduct = new Product(this.name);


container.push(pushedProduct);




try ...{


Thread.sleep((int)(Math.random()*2000));


}




catch (InterruptedException e) ...{


e.printStackTrace();


}


this.container.notifyAll();


}


}


}


}




/**//* 消费者 */




class Consumer implements Runnable ...{


private String name;


private Container container = null;


//Constructor




public Consumer(String consumerName,Container container) ...{


this.name = consumerName;


this.container = container;


}


//Override abstract methoed of Interface Runnable.




public void run() ...{




while(true) ...{




synchronized (this.container) ...{




while(this.container.isEmpty()) ...{




try ...{


this.container.wait();


}




catch (InterruptedException e) ...{


e.printStackTrace();


}


}


Product popedProduct = container.pop(name);




try ...{


Thread.sleep((int)(Math.random()*1000));


}




catch (InterruptedException e) ...{


e.printStackTrace();


}


this.container.notifyAll();


}


}


}


}




/**//* 产品 */




class Product ...{


private static int id = 0;


//Constructor


private String producerName;




public Product(String producerName) ...{


this.producerName = producerName;


this.id ++;


}


//Override method of Class Object.




public String toString() ...{


return "Product No."+id+"; Made by "+producerName;


}


}




/**//* 容器 只允许放一个产品 */




class Container ...{


private Product container = null;


//Test if the container is empty.




public boolean isEmpty() ...{




if (this.container==null) ...{


return true;


}




else ...{


return false;


}


}




public synchronized void push(Product product) ...{




if (this.isEmpty()) ...{


this.container = product;


System.out.println("Pushed: "+product);


}




else ...{


throw new RuntimeException("Can't push! The container is full.");


}


}




public synchronized Product pop(String consumerName) ...{




if (!this.isEmpty()) ...{


Product temp = this.container;


this.container = null;


System.out.println(consumerName+" poped: "+temp);


return temp;


}




else ...{


throw new RuntimeException("Can't pop! The container is empty.");


}


}


}

运行结果(死循环)
Pushed: Product No.1; Made by Alice
Charlie poped: Product No.1; Made by Alice
Pushed: Product No.2; Made by Lucy
James poped: Product No.2; Made by Lucy
Pushed: Product No.3; Made by Alice
Charlie poped: Product No.3; Made by Alice
Pushed: Product No.4; Made by Bob
James poped: Product No.4; Made by Bob
Pushed: Product No.5; Made by Alice
Charlie poped: Product No.5; Made by Alice
Pushed: Product No.6; Made by Lucy
James poped: Product No.6; Made by Lucy
Pushed: Product No.7; Made by Alice
Charlie poped: Product No.7; Made by Alice
Pushed: Product No.8; Made by Bob
James poped: Product No.8; Made by Bob
Pushed: Product No.9; Made by Alice
Charlie poped: Product No.9; Made by Alice
Pushed: Product No.10; Made by Lucy
James poped: Product No.10; Made by Lucy
。。。 。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: