`

生产者-消费者问题

阅读更多

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

多进程/ 线程编程:生产者 - 消费者问题。( 1 人)                      

设置两类进程/ 线程,一类为生产者,一类为消费者;

建立缓冲区的数据结构;

随机启动生产者或消费者;

显示缓冲区状况;

随着进程/ 线程每次操作缓冲区,更新显示;

 

package ProducerAndConsumer;

import java.util.ArrayList ;
import java.util.List ;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TestProducerConsumer extends JFrame {
	
	//窗体属性
	public static final int WIDTH =600 ;
	public static final int HEIGHT = 600 ;


	private JPanel pane1 ;
	private JPanel pane2 ;
	

	
	public static JTextArea textArea ;
	public static JTextField textBox ;   //手动设置缓冲区最大值
	public static JScrollPane scrollPane ;
	public JProgressBar progressBar = new JProgressBar() ;  //用进度条表示缓冲区存放产品情况

	Queue q = new Queue() ;     //创建一个消息队列对象
	private Thread threadWQ ;   //生产者线程
	private Thread threadRQ ;   //消费者线程
	Producer WQ = new Producer(q) ;
	Consumer RQ = new Consumer(q) ;
	
	
	
	public TestProducerConsumer(){
		
		pane1 = new JPanel() ;
		pane2 = new JPanel() ;
		
		setSize(WIDTH,HEIGHT) ;
		
		Toolkit too = Toolkit.getDefaultToolkit() ;
		Dimension screen = too.getScreenSize() ;
		int X = (screen.width-WIDTH)/2 ;
		int Y = (screen.height-HEIGHT)/2 ;
		setLocation(X,Y) ;
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;
		//this.setVisible(true) ;
	 
		layoutPane1() ;
		layoutPane2() ;
		
		setLayout(new BorderLayout()) ;
		add(pane1,BorderLayout.SOUTH) ;
		add(pane2,BorderLayout.NORTH) ;
	}
	
	public void layoutPane2(){
		
		JButton b1 = new JButton("开始模拟") ;
		JButton b2 = new JButton("暂停模拟") ;
		JButton b3 = new JButton("恢复运行") ;
		JButton b4 = new JButton("停止模拟") ;
		JButton b5 = new JButton("暂停生产") ;
		JButton b6 = new JButton("暂停消费") ;
		JButton b7 = new JButton("恢复消费") ;
		JButton b8 = new JButton("恢复生产") ;
		JButton b9 = new JButton("关闭") ;
		
		textBox = new JTextField("9",2) ;
		
		b1.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				
				threadWQ = new Thread(WQ,"Thread-WQ1") ;
				
				threadRQ = new Thread(RQ,"Thread-RQ1") ;
				
				q.maxMessageNum = Integer.parseInt(textBox.getText()) ;
				
				progressBar.setMaximum(q.maxMessageNum) ;
				
				threadWQ.start() ;   //开始模拟
				threadRQ.start() ;
				textArea.append("所有线程已开始运行" + "\n") ;
			}
		}) ;
		
		b2.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				threadWQ.suspend() ;
				threadRQ.suspend() ;
				textArea.append("已暂停模拟" + "\n") ;
			}
		}) ;
		
		b3.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				textArea.append("正在恢复..." + "\n") ;
				threadWQ.resume() ;
				threadRQ.resume() ;
				textArea.append("已恢复\n") ;
			}
		}) ;
		b4.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				textArea.append("停止模拟中..." + "\n") ;
				threadWQ.stop() ;
				threadRQ.stop() ;
				textArea.append("所有线程已停止" + "\n") ;
			}
		}) ;
		b5.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				textArea.append("正在暂停生产...\n") ;
				threadWQ.suspend() ;
				textArea.append("已暂停生产\n") ;
			}
		}) ;
		b6.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				textArea.append("正在暂停消费...\n") ;
				threadRQ.suspend() ;
				textArea.append("已暂停消费\n") ;
			}
		}) ;
		b7.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				textArea.append("正在恢复消费...\n") ;
				threadRQ.resume()  ;
				textArea.append("已恢复消费\n") ;
			}
		}) ;
		b8.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				textArea.append("正在恢复生产...\n") ;
				threadWQ.resume() ;
				textArea.append("已恢复生产\n") ;
			}
		}) ;
		b9.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				textArea.append("关闭中...") ;
				System.exit(0) ;
			}
		}) ;
		
		pane1.setLayout(new GridLayout(4,3)) ;
		pane1.add(textBox) ;
		pane1.add(b1) ;
		pane1.add(b4) ;
		pane1.add(b5) ;
		pane1.add(b8) ;
		pane1.add(b6) ;
		pane1.add(b7) ;
		pane1.add(b2) ;
		pane1.add(b3) ;
		pane1.add(b9) ; 
		
	}
	
	public void layoutPane1()
	{
		textArea = new JTextArea(25,25) ;
		progressBar.setEnabled(true) ;
		textArea.append("\n请按开始按钮") ;
		textArea.setEditable(false) ;
		textArea.setBackground(Color.pink) ;
		scrollPane = new JScrollPane(textArea) ;
		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) ;
		pane1.setLayout(new BorderLayout()) ;
		pane2.add(scrollPane,BorderLayout.NORTH) ;
		pane2.add(progressBar,BorderLayout.SOUTH) ;
	}




	
	//定义一个接口
	interface putMSG
	{
		public void output(String msg, JTextArea textArea, JProgressBar progressBar) ;//更新生产消费情况
		public void buffer(JTextField num) ;//设置缓冲区最大值
	}
	

	//消息类,产品
	static class Message {
		
		public static int id ;   //序列号
		public String content ; //消息内容
		
		public String getContent(){
			return this.content ;
		}
		
		public void setContent(String content){
			this.content = content ;
		}
		
		public int getId(){
			return this.id ;
		}
		
		public void setId(int id){
			this.id = id ;
		}
		
	}

	
	
	//消息队列类
	class Queue implements putMSG {

		List<Message> queue = new ArrayList<Message>() ;

		int maxMessageNum ;    //缓冲区最大值
		
		public synchronized void produce(Message message)
		{  //生产产品,用synchronized关键字实现同步
			
			this.notifyAll() ;
			
			while(queue.size() == maxMessageNum){
				
				output(Thread.currentThread().getName() + "缓冲区已满,等待中...."
							,textArea,progressBar) ;
				try{
					this.wait() ;
				}catch(InterruptedException e){
					System.err.println("Interrupted") ;
				}
			}
			queue.add(message) ;
			
			output(Thread.currentThread().getName()+"生产"
				+message.getContent()+"...当前产品数量:" 
					+ getCount(),textArea,progressBar) ;
		}
		
		public synchronized void consume(){//消费
			
			this.notifyAll() ;
			
			while(queue.size() == 0){
				output(Thread.currentThread().getName() + "缓冲区已空,等待中...."
						,textArea,progressBar) ;
				try{
					output("等待生产...",textArea,progressBar) ;
					this.wait() ;
					//output("等待结束",textArea,progressBar) ;
				}catch(InterruptedException e){
					e.printStackTrace() ;
				}
			}
			
			Message message = queue.get(0) ;
			queue.remove(0) ;
			output(Thread.currentThread().getName() + "正在消费" + message.getContent() 
				+ "...当前产品数量:" + getCount(),textArea,progressBar) ;
		}
		
		public synchronized int getCount(){
			return queue.size() ;
		}
		
		public void buffer(JTextField num) {
			 
			this.maxMessageNum = Integer.parseInt(num.getText()) ;
		}

		
		public void output(String msg, JTextArea textArea, JProgressBar progressBar) {
			 
			textArea.append(msg+"\n") ;
			textArea.append("当前容量:" + this.getCount() + "\n\n") ;
			progressBar.setValue(this.getCount()) ;
		}
	}
	
	
	
	
	
		//生产者类,继承Thread类
	class Producer extends Thread {

		private Queue queue ;
		
		Producer(Queue queue){
			this.queue = queue ;
		}
		
		public void run(){
			for(int i = 0; i < 100; i ++){   //生产者总共生产100个产品
				Message msg = new Message() ;
				msg.setId(++Message.id) ;
				msg.setContent("产品" + Message.id) ;
				queue.produce(msg) ;
				try{
					sleep(1000) ;
				}catch(InterruptedException e){
					System.out.println(e.getMessage()) ;
				}
			}
		}
	}
    
	//消费者类,继承Thread类
	class Consumer extends Thread {

		private Queue queue ;
		
		Consumer(Queue queue){
			this.queue = queue ;
		}
		
		public void run(){
			for(int i=0; i<100; i ++){
				queue.consume() ;
				try{
					sleep(2000) ;
				}catch(InterruptedException e){
					e.printStackTrace() ;
				}
			}
		}
	}
	
	
	
	public static void main(String[] args)
	{
		new TestProducerConsumer().setVisible(true) ;
	}
		

}


 
1
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics