7、线程的通信

该博客展示了如何使用Java实现生产者消费者问题,通过Clerk类模拟商品库存,Productor和Customer类分别代表生产者和消费者线程。在多线程环境下,使用wait(), notifyAll()进行线程通信,确保资源的正确使用和同步。同时,还提供了一个示例展示了如何用两个线程交替打印1-100。
摘要由CSDN通过智能技术生成

线程通讯需要到的重要方法:
wait():令当前线程挂起并放弃CPU、同步资源,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问
notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
notifyAll ():唤醒正在排队等待资源的所有线程结束等待.

/*
 * 生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,
 * 店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,
 * 如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,
 * 如果店中有产品了再通知消费者来取走产品。
 * 生产者和消费者线程,如果都各有一个,那么唤醒的时候可以使用notify()唤醒,因为只有一个线程等待唤醒。
 * 但是如果生产者和消费者线程是多个,那么使用notify()唤醒就会随机唤醒,就有肯能造成错误,这个时候需要使用notifyAll()。
 * 需要将原来使用if判断的wait判断块改成使用while判断。
 */
public class TestClerk {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Clerk clerk = new Clerk();
		Productor p = new Productor(clerk);
		Productor p1 = new Productor(clerk);
		Productor p2 = new Productor(clerk);
		p.start();
		p1.start();
		p2.start();
		Customer c = new Customer(clerk);
		Customer c1 = new Customer(clerk);
		Customer c2 = new Customer(clerk);
		c.start();
		c1.start();
		c2.start();

	}

}

class Clerk {
	private int product = 20;

	public int getProduct() {
		return product;
	}

	public void setProduct(int product) {
		this.product = product;
	}

	// 保存一个商品
	public synchronized void save() {
		//if(product >= 20){//只有一个消费线程的时候可以使用if判断。
		while(product >= 20){//有多个消费线程的时候需要使用while。
			System.out.println("现在商品已经达到上限,先让消费线程消费一会儿吧~~~~~~~~~~~~~~~~");
			try {
				this.wait();//当前线程进入等待状态
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		product++;
		System.out.println("生产线程生产了一个商品,此时商品数量是:" + getProduct());
		//this.notify();//唤醒另外一个线程。
		this.notifyAll();//唤醒所有线程。
	}

	// 消费一个商品
	public synchronized void get() {
		//if(product <= 0){//只有一个生产线程的时候可以使用if
		while(product <= 0){//有多个生产线程的时候需要是while
			System.out.println("当前已经没有任何商品了,让生产线程生产一会儿吧======================");
			try {
				this.wait();//当前线程进入等待状态
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		product--;
		System.out.println("消费线程消费了一个商品,此时商品数量是:" +getProduct());
		//this.notify();//唤醒另外一个线程。
		this.notifyAll();//唤醒所有线程
	}

}

class Productor extends Thread {
	private Clerk clerk;

	public Productor(Clerk clerk) {
		super();
		this.clerk = clerk;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			clerk.save();
		}
	}

}

class Customer extends Thread {
	private Clerk clerk;

	public Customer(Clerk clerk) {
		super();
		this.clerk = clerk;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			clerk.get();
		}
	}
}

使用两个线程打印 1-100. 线程1, 线程2 交替打印

public class TestShowOneTwo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ShowNumberTwo st = new ShowNumberTwo();
		Thread one = new Thread(st);
		one.setName("肯德基线程");
		one.start();
		Thread two = new Thread(st);
		two.setName("麦当劳线程");
		two.start();
	}

}

class ShowNumberTwo implements Runnable {

	@Override
	public void run() {
		
		for (int i = 1; i <= 100; i++) {
			synchronized (this) {
				this.notify();
				System.out.println(Thread.currentThread().getName() + "线程正在打印===================="+i);
				try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值