我一直对多线程掌握的不够好,感觉没搞透实质,想问下这道题我这样写可不可以,不可以的话,怎么写才更好,真心求教。这是题目:采用Java 多线程技术,设计实现一个符合生产者和消费者问题的程序。对一个对象(枪膛)进行操作,其最大容量是12颗子弹。生产者线程是一个压入线程,它不断向枪膛中压入子弹;消费者线程是一个射出线程,它不断从枪膛中射出子弹。(30分)
要求:
(1)给出分析过程说明。(10分)
(2)程序输出,要模拟体现对枪膛的压入和射出操作;(10)
(3)设计程序时应考虑到两个线程的同步问题。(10)分析说明:一个子弹类,一个生产者线程,一个消费者线程,生产者线程执行压入子弹操作,消费者线程执行射出子弹操作。当前线程为生产者线程时,若枪膛子弹数未满,则压入子弹即子弹数加一,否则该线程等待。当前线程为消费者线程时,若枪膛子弹数不为空,则射出子弹即子弹数减一,否则该线程等待。我的代码:import java.awt.*;
import java.awt.event.*;import javax.swing.*;public  class QiangTang extends JFrame implements Runnable,ActionListener{
int bullet=12;
Thread maker;
Thread consumer;
Container con;
JPanel panel=new JPanel();
JButton start=new JButton("start");JTextArea area=new JTextArea();
QiangTang()
{
 con=getContentPane();
 panel.add(start);
 start.addActionListener(this);
 con.add(panel,BorderLayout.NORTH);
 con.add(new JScrollPane(area),BorderLayout.CENTER);
 setVisible(true);
 setBounds(400,100,500,600);
 this.setDefaultCloseOperation(EXIT_ON_CLOSE);
 
 
}
public void actionPerformed(ActionEvent e)
{
 area.setText("");
 maker=new Thread(this);
 consumer=new Thread(this);
 if(e.getSource()==start)
 {
  
  maker.start();
  consumer.start();
  
  
 }}
public synchronized void run()
{
 int i=100;
 while(i>0)
 {
  if(Thread.currentThread()==maker)              //当前线程为生产者线程
  {
   if(bullet==12)
   {
    try {
     area.append("枪膛已满"+"\n");
     wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   bullet++;
   area.append("压入子弹,子弹数:"+bullet+"\n");
   i--;
  }
  else if(Thread.currentThread()==consumer)            //当前线程为消费者线程
  {
   if(bullet==0)
   {
    try {
     area.append("枪膛无子弹"+"\n");
     wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   bullet--;
   area.append("弹出子弹,子弹数:"+bullet+"\n");
   i--;
  }
  this.notifyAll();
 }
}
public static void main(String []args)
{
 new QiangTang();
}
}

解决方案 »

  1.   

    哈哈~这个让我想起了 操作系统 关于 信号量semaphore  生产者消费者问题了~
      

  2.   

    之前有一帖也有这题,直接套用我原来的回复好了= =:
    public class Test1 
    {

    public static void main(String[] args) throws Exception {
    AK_47 ak = new AK_47();
    In in = new In(ak);
    Out out = new Out(ak);
    new Thread(in).start();
    new Thread(out).start();
    }


    }class AK_47 {  //枪
    int max = 12;   //枪子弹最大数目
    int num = 0;    //当前子弹数目
    int in = 0;         //记录总共装了子弹数目
    int out = 0;      //记录总共射出子弹数目
    public  void in() {
    if(num==12) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    this.notify();
    num++;
    in++;
    System.out.println("上子弹: "+num+"    "+"已经上子弹总数:"+in);
    }

    public void out() {
    if(num==0) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    this.notify();
    num--;
    out++;
    System.out.println("射子弹: "+num+"     "+"已经射子弹总数"+out);
    }
    }class Out implements Runnable {    //消费者 AK_47 ak;
    public Out(AK_47 ak) {
    this.ak = ak;
    }
    public void run() {
    for(int i = 0; i < 30;i++) {
    synchronized(this.ak) {
    ak.out();
    }
    }
    }
    }class In implements Runnable {     //生产者 AK_47 ak;
    public In(AK_47 ak) {
    this.ak = ak;
    }

    public void run() {
    for(int i =0; i< 30;i++) {
    synchronized(this.ak) {
    ak.in();
    }
    }
    }
    }
      

  3.   


    package com.ssj.test;import java.util.Random;
    import java.util.concurrent.Semaphore;public class FireTest {
    private Semaphore sem;
    private int maxSize; private Random random = new Random(); /**
     * 
     * @param initSize枪中子弹初始数目
     * @param maxSize枪最大可装弹数
     * 
     */
    public FireTest(int initSize, int maxSize) {
    sem = new Semaphore(initSize);
    this.maxSize = maxSize;
    } public void test() {
    new Shoot().start();
    new Load().start();
    } public static void main(String[] args) {
    new FireTest(5, 12).test();
    } class Shoot extends Thread {
    @Override
    public void run() {
    while (!Thread.interrupted()) {
    try {
    Thread.sleep(random.nextInt(2) * 1000);
    sem.acquire();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("shoot!");
    synchronized (sem) {
    sem.notifyAll();
    }
    }
    }
    } class Load extends Thread {
    @Override
    public void run() {
    while (!Thread.interrupted()) {
    try {
    Thread.sleep(random.nextInt(2) * 1000);
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    } if (sem.availablePermits() == maxSize)
    synchronized (sem) {
    try {
    System.out.println("full");
    sem.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    System.out.println("load!");
    sem.release();
    }
    }
    }
    }
    生产者消费者模式,信号量很nice