线程的交互

生产者消费者问题是一个非常典型性的线程交互的问题。

  1. 使用栈来存放数据
    1.1 把栈改造为支持线程安全
    1.2 把栈的边界操作进行处理,当栈里的数据是0的时候,访问pull的线程就会等待。 当栈里的数据是200的时候,访问push的线程就会等待
  2. 提供一个生产者(Producer)线程类,生产随机大写字符压入到堆栈
  3. 提供一个消费者(Consumer)线程类,从堆栈中弹出字符并打印到控制台
  4. 提供一个测试类,使两个生产者和三个消费者线程同时运行,

栈:

public class MyStack{
LinkedList list = new LinkedList<>();
//用泛型类定义较好,避免重复定义
// LinkedList list = (LinkedList)

Collections.synchronizedList(linked);

public synchronized void push(T t)
{
	while(list.size()>=200)
	{
		try {
			this.wait();
		}catch(InterruptedException e)
		{
			e.printStackTrace();
		}
	}

// 当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或
// notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,
// 锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,
// 而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争

	this.notifyAll();
	list.addLast(t);
}

public synchronized T pull()
{
	while(list.size()<=0)
	{
		try {
			this.wait();
		}catch(InterruptedException e)
		{
			e.printStackTrace();
		}
	}

	this.notifyAll();
	return list.removeLast();
}
}

测试类:
public class TestStack {

public static void main(String[] args) {
	MyStack<Character> ms = new MyStack<>();
	Producer []p = new Producer[2];
	Consumer []c = new Consumer[3];
	
	for(int i=0;i<p.length;i++)
	{
		new Producer(ms,"Producer"+i).start();
	}
	
	for(int i=0;i<c.length;i++)
	{
		new Consumer(ms,"Consumer"+i).start();
	}
}

消费者类:
public class Consumer extends Thread{

private MyStack<Character> stack;
public Consumer(MyStack<Character> ms,String name)
{
	super(name);
	this.stack = ms;
}

public void run()
{
	while(true) {
	char c = stack.pull();
	System.out.println(this.getName()+" 弹出 : " +c);	
	try {
		Thread.sleep(1000);
	}catch(InterruptedException e)
	{
		e.printStackTrace();
	}
	}
}

生产者类:
public class Producer extends Thread{

private MyStack<Character> stack;
private char character;

public Producer(MyStack<Character> ms,String name)
{
	super(name);
	this.stack = ms;
}

public void run()
{
	while(true)
	{
		char character = this.getChar();
	
	System.out.printf("%s 压入  %c%n",this.getName(),character);
	stack.push(character);
	try {
		Thread.sleep(1000);
	}catch(InterruptedException e)
	{
		e.printStackTrace();
	}
	}
}

private Character getChar()
{
	Character character;
	while(true)
	{
	char a = (char)(Math.random()*128);
	if(Character.isLetter(a)) {
		character = Character.toUpperCase(a);
		break;
	}
	else continue;
	}
	return character;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pascalzhli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值