多线程(生产者与消费者)

需求:有一个箱子,一个男孩往里面放水果,等到箱子里满了以后,一个女孩去箱子里去水果,等箱子里水果没了,男孩再放水果进去。

1.定义一个Box类.

package org.demo;

import java.util.LinkedList;

public class Box {
 
	//定义一个集合,指定存放的是水果
	private LinkedList<Fruit> box = new LinkedList<Fruit>();
	
	//箱子提供一个put行为,让男孩往里面存放水果 
	public synchronized void put(Fruit fruit) throws Exception{
		//如果箱子是空的,那么就把水果放进箱子
		if(box.size()==5){
			System.out.println("箱子满了,通知女孩来取...");
			//wait之前必须先调用notifyAll()或者notify()方法
			this.notifyAll();
            //把自己停下,让女孩的线程来执行
			//wait方法是让当前正在执行的线程进入一个叫做等待队列的集合中
			//等待队列是由key所创建的
			//如果wait方法后面还有代码,将全部忽略
			//如果当前线程从等待队列出来后将会继续执行wait方法后的代码
			//如果当前线程进入了等待队列后,也将释放钥匙
			this.wait();
		}
		box.add(fruit);
		Thread.sleep(200);
	}
	
	//箱子提供一个take行为让女孩子提取水果
	public synchronized Fruit take() throws Exception{
		if(box.size()==0){
			System.out.println("箱子空了,通知男孩放入水果...");
			this.notifyAll();
			//将女孩的线程放入key所产生的等待队列
			this.wait();
		}
		Fruit fruit = box.removeFirst();
		Thread.sleep(200);
		return fruit;
	}
}


2.定义一个Boy类,此类继承Thread类.

package org.demo;

public class Boy extends Thread{
	
	private Box box;
	
	public Boy(Box box){
		this.box = box;
	}

	public void run(){
		//在一个死循环当中不停的调用put方法
		while(true){
			Fruit fruit = new Fruit();
			try {
				box.put(fruit);
				System.out.println("男孩放入了一个"+fruit);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

3.定义一个girl类,并且继承Thread类.

package org.demo;

public class Girl extends Thread{

	private Box box;
	
	public Girl(Box box){
		this.box = box;
	}
	
	public void run(){
		//不停的调用take方法
		while(true){
			try {
				Fruit fruit = box.take();
				System.out.println("女孩从盒子中取出一个"+fruit);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
}

4.定义一个Fruit类

package org.demo;

import java.util.Random;

public class Fruit {

	private String[] fruit = {"苹果","香蕉","葡萄","芒果","荔枝"};
	private int index;
	
	public Fruit(){
		//随机数组,返回一个下标
		index = new Random().nextInt(fruit.length);
	}
	
	//重写toString方法
	public String toString(){
		return fruit[index];
	}
}


5.演示一下

package org.demo;

public class Demo {

	public static void main(String[] args) {
		 Box box = new Box();
		 Boy boy = new Boy(box);
		 Girl girl = new Girl(box);
		 boy.start();
		 girl.start();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
后台采用apache服务器下的cgi处理c语言做微信小程序后台逻辑的脚本映射。PC端的服务器和客户端都是基于c语言写的。采用mysql数据库进行用户数据和聊天记录的存储。.zip C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。
线生产者消费者问题是一个经典的并发编程问题,主要涉及到线程间的同步和互斥。在这个问题中,有一个生产者线程和一个消费者线程,它们共享一个缓冲区。生产者线程负责往缓冲区中生产数据,而消费者线程则负责从缓冲区中消费数据。为了保证线程安全,需要使用锁或信号量等机制来实现线程间的同步和互斥。 下面是一个简单的多线生产者消费者的示例代码: ```python import threading import time # 缓冲区大小 BUFFER_SIZE = 10 # 生产者线程 class ProducerThread(threading.Thread): def __init__(self, buffer): threading.Thread.__init__(self) self.buffer = buffer def run(self): for i in range(20): # 生产数据 data = "data-%d" % i # 加锁 self.buffer.lock.acquire() # 如果缓冲区已满,等待消费者消费数据 while len(self.buffer.data) == BUFFER_SIZE: self.buffer.full.wait() # 将数据放入缓冲区 self.buffer.data.append(data) print("ProducerThread: produce %s" % data) # 释放锁 self.buffer.lock.release() # 通知消费者可以消费数据了 self.buffer.empty.notify() # 消费者线程 class ConsumerThread(threading.Thread): def __init__(self, buffer): threading.Thread.__init__(self) self.buffer = buffer def run(self): for i in range(20): # 加锁 self.buffer.lock.acquire() # 如果缓冲区为空,等待生产者生产数据 while len(self.buffer.data) == 0: self.buffer.empty.wait() # 从缓冲区中取出数据 data = self.buffer.data.pop(0) print("ConsumerThread: consume %s" % data) # 释放锁 self.buffer.lock.release() # 通知生产者可以生产数据了 self.buffer.full.notify() # 缓冲区 class Buffer: def __init__(self): self.data = [] self.lock = threading.Lock() self.full = threading.Condition(self.lock) self.empty = threading.Condition(self.lock) if __name__ == "__main__": buffer = Buffer() producer_thread = ProducerThread(buffer) consumer_thread = ConsumerThread(buffer) producer_thread.start() consumer_thread.start() producer_thread.join() consumer_thread.join() ``` 在上面的代码中,我们使用了一个列表来作为缓冲区,使用了 threading.Lock 来实现线程间的互斥,使用了 threading.Condition 来实现线程间的同步。具体来说,我们使用了 full 条件变量来表示缓冲区已满,empty 条件变量来表示缓冲区为空。当生产者线程往缓冲区中生产数据时,如果缓冲区已满,则调用 full.wait() 来等待消费者线程消费数据;当消费者线程从缓冲区中消费数据时,如果缓冲区为空,则调用 empty.wait() 来等待生产者线程生产数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值