简体   繁体   中英

mutual exclusion over variables does not work

i am trying to simulate visitors going into a theater and taking an aailable sit(the number of available sits is shared) and once all the sits are taken the rest go to sleep. i am having trouble over the availablesits variable in the getsit method inside the visitor class. please help me

i tried synchronizing the threads as well as making the variable volatile. but for some reasons all threads arrive to that getsit part at the same time? i dont understand why! //main

import java.util.ArrayList;
public class Main {
    public static void main(String[] args) {
        int numVisitors = 23;
        int theaterCapacity =5;
        int party_ticket=3;
        Clock clock = new Clock();
        Theater theater=new Theater(theaterCapacity,clock);
        ArrayList<Visitor> visitorlist = new ArrayList<Visitor>();
        for(int i=1;i<=numVisitors;i++) {
            visitorlist.add(new Visitor(i,clock,theater));
        }
        clock.start();
        for(Visitor visitor:visitorlist)
            visitor.start();

    }
}

//visitor class

  public class Visitor extends Thread{


  private static Clock clock;
    private static Theater theater;
    public int id;
    public boolean sawPresentation=false;
    public volatile int priority= 10;
    public static long time = System.currentTimeMillis();
    public void msg(String m) {
        System.out.println("["+(System.currentTimeMillis()-time)+"] "+getName()+": "+m);
    }
    Visitor(int id, Clock clock, Theater theater){
        this.id=id;
        this.clock=clock;
        this.theater=theater;
    }
    public void run(){
        heArrives();
        while(!sawPresentation) {
            while(!clock.presentationIsOpen()) {
                //busy wait
            }
            getASit();
        }
    }
    public void heArrives() {
      msg("the visitor arrived");
    }
    public synchronized  void getASit(){
        if(theater.availableSits>0){
            msg("the visitor got a sit");
            theater.availableSits--;
            watchPresentation();
        }
    }
    public void watchPresentation(){
        msg("the visitor is watching the presentation");
    }
}

//clock class

import java.util.Timer;
import java.util.TimerTask;
public class Clock extends Thread {
    public static long time = System.currentTimeMillis();
    public static int secondsPassed=6;
    Timer timer= new Timer();

    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            secondsPassed++;
            //System.out.println("seconds passed: "+secondsPassed);
        }
    };
    public void run(){
        timer.scheduleAtFixedRate(task,0,1000);
    }
    public boolean presentationIsOpen(){
        if(secondsPassed%6==0) return true;
        return false;
    }
}

//theater class

class Theater extends  Thread{
    public static Clock clock;
    public int capacity;
    public volatile int availableSits=5;
    Theater(int capacity,Clock clock){
        this.capacity=capacity;
        this.clock=clock;
    }
}

Your main problem is the synchronization of the getASit method.You are synchronizing against Visitor object instance so every thread synchronized against diferent object. Instead you have to synchronized against the object that is shared. In your case against the theater. Change your method to something like this:

 public   void getASit(){
    synchronized(theater){
        if(theater.availableSits>0){
            msg("the visitor got a sit");
            theater.availableSits--;
            watchPresentation();
        }
      }
    }

Its better not to use busy wait, its burn cpu too much, better is to use sleep for example:

while(!clock.presentationIsOpen()) {
          try {
              Thread.sleep(1_000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM