<!-- [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 人)
l 设置两类进程/ 线程,一类为生产者,一类为消费者;
l 建立缓冲区的数据结构;
l 随机启动生产者或消费者;
l 显示缓冲区状况;
l 随着进程/ 线程每次操作缓冲区,更新显示;
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) ;
}
}