最近在做一个停车场管理的题目 要求实时显示现在有多少辆车,
我用4个线程共享一个变量去做,但是每次显示的时候都会有有莫名其妙的数字出现
比如 exit1 从50....40  exit2 会突然显示50 然后再从39开始减下去。
我把源程序贴下面!~~~CarPark
import java.lang.Thread;public class CarPark{ 
    entrance entrance1; 
   entrance entrance2;// Declare shared variables
    exit exit1;
    exit exit2;
    share share;
    
    public CarPark()
    {
         share share= new share();
         entrance1 = new entrance("entrance1", 50);
         entrance2 = new entrance("entrance2", 50);
         exit1 = new exit("exit1", 50);
         exit2 = new exit("exit2", 50);
         
         entrance1.start();
        entrance2.start();
        exit1.start();
        exit2.start();        do{
            if((exit1.isAlive() || exit2.isAlive() || entrance1.isAlive() || entrance2.isAlive() ) == false)
               {
                   System.out.println("end");
               }
            }
        while(exit1.isAlive()||exit2.isAlive()||entrance1.isAlive()||entrance2.isAlive());
        
    }
}Entrance 
import java.lang.Thread;public class entrance extends Thread

    private int max;
    private int a;
    private int b;
    private int c;
    private String Entrance;
 
public entrance (String entrance,int m)
{
    Entrance = entrance;
     max =50;
     a = m;
    }public void run()

 try {
            this.sleep(500);
            } catch (InterruptedException e){};
    for(int temp = 0; temp < a; temp ++)
    {
        if( share.getAvailable() <= max && share.getAvailable() > 1)
        {
            --share.available;
            System.out.println(Entrance+" There are "+share.getAvailable()+" Sapce !");
            
        }
        else
        {        
                        
                System.out.println(Entrance+": There are no parking sapce !");
               
            }
        
        
    }
     System.out.println(Entrance+":Terminated !");}
}Eixt
import java.lang.Thread;public class exit extends Thread

    private int max;
    private int a;
    private int b;
    private String Exit;
    
public exit (String exit,int m )
{
    Exit = exit;
     max =50;
     a = m;
}public void run()

try {
            this.sleep(500);
            } catch (InterruptedException e){};
    for(int temp = 0; temp < a; temp ++)
    {
        if( share.getAvailable() == max )
        {
            System.out.println(Exit+" There are 50 Parking Space !");
            
        }
        else
            {
                ++share.available;
                System.out.println(Exit+" There are "+ share.getAvailable() +" Parking Space !");
            }
       
     }    System.out.println(Exit+":Terminated !");
}
}share
import java.lang.Thread;public class share extends Thread

    public static int available ;
        static{
                share.available = 50;
            }    static int getAvailable(){
        return available;
    }
    public void share()
    {
        System.out.println("50 Berth Parkingn!");
    }
}

解决方案 »

  1.   

    扫了一眼代码,没看见同步块和同步方法。建议LZ再好好的把JAVA线程学一下
      

  2.   

    如果你对线程不太理解,你可以用JDK里的队(1.5才有)
    把数据放到队里,用一个线程看着,没有队员就等着,其它的线程往队里加包装好的数据。
    只要有数据,就提出,处理,这样就不会出问题(进出队要用synchronized标记)
    如果你用1.4,我写个类给你。
      

  3.   

    队类:
    import java.util.Vector;/**
     * 队
     * @author guishuanglin 2008-11-20
     *
     */
    public class Queue extends Vector{
    /**
     * @author guishuanglin 2008-11-20
     */
    private static final long serialVersionUID = 1L;

        /**
         * Creates an empty Stack.
         */
    public Queue() {

        } /**
     * put in object
     * @date 2008-11-20
     * @param o
     * @return
     */
    public synchronized boolean offer(Object o) {
    return add(o);
    } /**
     * get object,but not remove.
     * @date 2008-11-20
     * @return
     */
    public synchronized Object peek() {
    if (isEmpty())
    return null;
    return firstElement();
    } /**
     * get object and remove
     * @date 2008-11-20
     * @return
     */
    public synchronized Object poll() {
    if (isEmpty())
    return null;
    return remove(0);
    }
      

  4.   


    /**
     * 线程请求队列,用来处理多线程并发排队.
     * 实际用的是先进先出的堆栈 Queue,默认队大小为128
     * @author guishuanglin 2008-11-3
     * 
     */
    public class ConcurrentQueue {
    private Queue QUEUE;
    private int QUEUE_SIZE = 128;
    private String QUEUE_NAME = "Queue";

    public ConcurrentQueue() {
    QUEUE = new Queue();
    printQueueSize();
    }
    public ConcurrentQueue(int size) {
    QUEUE_SIZE = size;
    QUEUE = new Queue();
    printQueueSize();
    }
    public ConcurrentQueue(int size,String name) {
    QUEUE_SIZE = size;
    QUEUE_NAME = QUEUE_NAME+"["+name+"]";
    QUEUE = new Queue();
    printQueueSize();
    } /**
     * 入队
     * @param call
     */
    public synchronized void enQueue(Object call) {
    while (QUEUE.size() > QUEUE_SIZE) {
    try {
    System.out.println(QUEUE_NAME+" wait enQueue....");
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    QUEUE.add(call);
    notifyAll();
    //System.out.println("入队");
    } /**
     * 出队
     * @param call
     */
    public synchronized Object deQueue() {
    Object call;
    while (QUEUE.isEmpty()) {
    try {
    System.out.println(QUEUE_NAME+" wait deQueue....");
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    call = QUEUE.poll();
    notifyAll();
    //System.out.println("出队");
    return call;
    }
    /**
     * 打印当前队大小
     * @date 2008-11-4
     */
    public int size(){
    return QUEUE.size();

    }
    /**
     * 清空队
     * @date 2008-11-4
     */
    public void clear(){
    QUEUE.clear();
    }
    /**
     * 测试队是否有元素
     * @date 2008-11-4
     */
    public boolean isEmpty(){
    return QUEUE.isEmpty();
    }
    /**
     * 打印当前队大小
     * @date 2008-11-4
     */
    private void printQueueSize(){
    System.out.println("Concurrent queue size: "+QUEUE_SIZE);
    }
      

  5.   

    多线程请求时,要排队处理。防止出现其它问题。
    最后,用一个线程来处理队。/**
     * 队列服务.用来查看线程队排中的请求.
     * 启动一个线程,用来跟踪队排里的客户请求.
     * 如果队中有客户的请求,则创建一个新线程独立处理,<br>
     * @author guishuanglin 2008-11-3
     * 
     */
    public class ConcurrentQueueService extends Thread {
    //IConcurrentCall
    private ConcurrentQueue _queue;

    /**
     * 启动一个线程来跟踪堆中需要处理的对象.
     * @param queue
     */
    public ConcurrentQueueService(ConcurrentQueue queue) {
    _queue = queue;
    start();
    } /**
     * 入队
     * @param call
     */
    public void enQueue(IConcurrentCall target) {
    _queue.enQueue(target);
    }

    /**
     * 单一线程跟踪队排请求,并把每个请求交给一个新线程处理.
     * 此处是否需要创建新的线程处理,有待实际需要,因为这将又产生线程并发问题.
     * @param call
     */
    public void run() {
    Runnable call = null;
    while (true) {
    call = (Runnable)_queue.deQueue();
    if(call != null){
    //可以不使用独立的线程处理,直接顺序处理.
    call.run();
    //new Thread(call).start();
    }
    }
    }
    }