多线程同步一例

注:本程序来自于《Java面向对象程序设计基础教程》冯洪海主编中的线程同步例子,我加上了一些注释,仅学习之用,欢迎指正。

记得wait()和notify()必须成对出现,否则会出现死锁。

Buffer.java

package lgw.util;

public class Buffer {
	private char chBuffer;
	private boolean empty = true; //信号量

	//往缓冲区放入资源
	public synchronized void put(char ch) {
		//P操作
		while(!this.empty) { //缓冲区不空,无法放入资源
			try {
				wait(); //其他线程(生产者线程)等待
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.chBuffer = ch;
		this.empty = false; //缓冲区标识为不空
		notify(); //V操作,通知其他线程(消费者线程)空闲
	}
	
	//从缓冲区中获取资源
	public synchronized char get() {
		//P操作
		while(this.empty) { //缓冲区为空,无法获取资源
			try {
				wait(); //其他线程(消费者线程)等待
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		char ch = this.chBuffer; //获得资源(字符)
		this.chBuffer = '\0'; //资源重置
		this.empty = true; //缓冲区标识为空
		notify(); //V操作,通知其他线程(生产者线程)空闲
		return ch; //返回资源给调用者
	}
}
Consumer.java
package lgw;

import lgw.util.Buffer;

//消费者线程,是线程类的子类
public class Consumer extends Thread {
	private Buffer br; //消费者拥有缓冲区,消费缓冲区的资源
	
	public Consumer(Buffer br) { //构造方法
		this.br = br;
	}
	
	@SuppressWarnings("static-access")
	public void run() {
		for(int i=1; i<=5; i++) { //当前消费者线程共消费5个资源
			System.out.println("hello,Consumer!");
			synchronized (br) { //缓冲区需要同步操作
				char ch = br.get(); //从缓冲区中取出资源(字符)
				if(ch != '\0') {
					System.out.println("消费者" + i + "消费了产品:" + ch);
				} else {
					System.out.println("消费者" + i + "没有产品可以消费");
				}
			}
			try {
				this.sleep(50); //消费1个资源后消费者线程休眠50毫秒
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
Procedure.java
package lgw;

import java.util.Random;

import lgw.util.Buffer;

//生产者线程
public class Procedure extends Thread {
	private Buffer br; //生产者拥有缓冲区,生产者生产资源放入缓冲区
	Random r = new Random(); //随机数类实例r用来产生随机数
	
	public Procedure(Buffer br) { //构造方法
		this.br = br;
	}
	
	@SuppressWarnings("static-access")
	public void run() {
		for(int i=1; i<=5; i++){ //消费者线程共消费5个资源
			System.out.println("hello,Procedure!");
			char ch = (char)(65 + r.nextInt(20)); //产生A~T的随机字符
			br.put(ch); //资源放入缓冲区
			System.out.println("生产者" + i + "生产了产品:" + ch);
			try {
				this.sleep(5);
			} catch(InterruptedException ex) {
				ex.printStackTrace();
			}
		}
	}
}
Test.java
package lgw;

import lgw.util.Buffer;

public class Test {
	public static void main(String args[]) {
		Buffer buffer = new Buffer(); //创建缓冲区buffer
		Procedure p = new Procedure(buffer); //用buffer初始化生产者
		Consumer c = new Consumer(buffer); //用buffer初始化消费者
		p.start(); //生产者开始生产
		c.start(); //消费者开始消费
	}
}
运行结果:

hello,Consumer!
hello,Procedure!
生产者1生产了产品:Q
消费者1消费了产品:Q
hello,Procedure!
生产者2生产了产品:O
hello,Procedure!
hello,Consumer!
消费者2消费了产品:O
生产者3生产了产品:N
hello,Procedure!
hello,Consumer!
消费者3消费了产品:N
生产者4生产了产品:T
hello,Procedure!
hello,Consumer!
消费者4消费了产品:T
生产者5生产了产品:A
hello,Consumer!
消费者5消费了产品:A

附:


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值