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

我们晦涩的操作系统课本也讲过 生产者-消费者问题,不过是由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
。。。 。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值