多线程进阶之三

一,生产者与消费者

         下面写一个生产窝头,消费窝头的例子来模拟生产者与消费者的情景,用面向对象的思维,下面分别有WoTou,Basket,Croduce,Customer几个对象.

         窝头Wotou对象,有一个含义id的构造方法,重写了toString()方法

package com.remote3c.main;

public class Wotou {
	private int id;

	public Wotou(int id) {
		super();
		this.id = id;
	}
	public String toString(){
		return "wotou : "+id;
	}
}
         篮子Basket对象,是整个例子的核心对象,有put()生产和set()消费两个方法,这两个方法分别用关键字Synchronized修饰,表示同步

  

package com.remote3c.main;

public class Basket {
	int index = 0;
	Wotou[] wotou = new Wotou[6];//假设篮子能装这么多个窝头
	//生产窝头
	public synchronized void put(Wotou w){
		while(index ==wotou.length){
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.notify();
		wotou[index]=w;
		index++;
	};
	//消费窝头
	public synchronized Wotou get(){
		while(index==0){
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.notify();
		index--;
		return wotou[index];
	}
}

    生产者Produce,含义篮子的构造方法,调用篮子的put()方法往篮子里添加wotou

package com.remote3c.main;

import java.util.concurrent.TimeUnit;

public class Producer implements Runnable {
	private Basket bt;
	public Producer(Basket bt) {
		this.bt = bt;
	}
	@Override
	public void run() {
			for(int i=0;i<20;i++){
				Wotou wotou = new Wotou(i);
				bt.put(wotou);
				System.out.println("生产了------- :"+wotou);
				try {
					TimeUnit.MILLISECONDS.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
	}

}
        消费者Customers,含义篮子的构造方法,调用篮子的get()方法从篮子里取wotou

package com.remote3c.main;

import java.util.concurrent.TimeUnit;

public class Customer implements Runnable {
	private Basket bt;
	
	public Customer(Basket bt) {
		super();
		this.bt = bt;
	}
	@Override
	public void run() {
		
			for(int i=0;i<20;i++){
				Wotou wotou =bt.get();
				System.out.println("消费了 :"+wotou);
				try {
					TimeUnit.MILLISECONDS.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		
	}

}
测试程序

package com.remote3c.main;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Basket basket =new Basket();
		Producer producer =new Producer(basket);
		Customer cusotmer=new Customer(basket);
		new Thread(producer).start();
		new Thread(cusotmer).start();
		
	}

}
输出结果

生产了------- :wotou : 0
消费了 :wotou : 0
生产了------- :wotou : 1
生产了------- :wotou : 2
生产了------- :wotou : 3
生产了------- :wotou : 4
生产了------- :wotou : 5
生产了------- :wotou : 6
消费了 :wotou : 6
生产了------- :wotou : 7
消费了 :wotou : 7
生产了------- :wotou : 8
消费了 :wotou : 8
生产了------- :wotou : 9
生产了------- :wotou : 10
消费了 :wotou : 9
消费了 :wotou : 10
生产了------- :wotou : 11
生产了------- :wotou : 12
消费了 :wotou : 11
生产了------- :wotou : 13
消费了 :wotou : 12
生产了------- :wotou : 14
消费了 :wotou : 13
消费了 :wotou : 14
生产了------- :wotou : 15
消费了 :wotou : 15
生产了------- :wotou : 16
消费了 :wotou : 16
生产了------- :wotou : 17
消费了 :wotou : 17
生产了------- :wotou : 18
消费了 :wotou : 18
生产了------- :wotou : 19
消费了 :wotou : 19
消费了 :wotou : 5
消费了 :wotou : 4
消费了 :wotou : 3
消费了 :wotou : 2
消费了 :wotou : 1

二,wait()方法

           1,wait()必须在同步控制块或方法内使用,否则运行时会报错。

           2,wait()与sleep()最大的差别是,wait会释放锁,而sleep睡着了也抱着那把锁。

           3,wait必须通过notify()或notifyAll()方法才能变为就绪状态

           4,wai,notify()和notifyAll()都是基类Object的方法,因为这些方法操作的锁是所有对象的一部分,所以可以把wait()放进任何同步方法里,而不用担心这个类时继承了Thread还是实现了Runnable接口。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值