Java信号量:没有正确阻塞和释放

时间:2013-12-09 07:16:40

标签: java concurrency semaphore

对于我当前的程序,我试图制作一个模拟交集程序,将4种方式中的每一种作为队列进入交集,并且队列中的每个线程都是" car"。每个模拟时钟滴答,允许汽车通过,修改不同的计数变量。

我目前的问题是,我的信号量控制时钟滴答声增加,并且驾车穿越交叉路口似乎无法正常运行。代码如下。

public class Intersection implements Runnable{

static ArrayList<Queue<Thread>> streets = new ArrayList<Queue<Thread>>();
static ArrayList<Thread> allThreads = new ArrayList<Thread>();
static int clk = 1;
static int numCars = 0;
static boolean empty = true;
static long state = 1;
static int carsRan = 0; 
static int carsMade = 0;
static int carsToRun = 0;

static Random randomGen = new Random();

static Semaphore carCanGo;
static Semaphore clkUp;

public static void main(String[] args) {

    carCanGo = new Semaphore(1);
    clkUp = new Semaphore(0);

    for(int i = 0; i < 4; i++){
        Queue<Thread> newStreet = new LinkedList<Thread>();
        streets.add(newStreet);
    }

    numCars = 50;

    if(numCars > 100){
        numCars = 100;
    }

    while(carsRan  < numCars && clk < 30){
        if(carsMade < numCars){
            newCarsArrive();
            if(carsToRun == 0){
                clkUp.release();
            }
        }

        System.out.println("clockups");

        for(int i = 0; i < allThreads.size(); i++){
            System.out.println(allThreads.get(i).isAlive());
        }

        try {
            clkUp.acquire();
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        clk++;
        carCanGo.release();
        System.out.println("clk: " + clk);

        //check for dead processes
        for(int i = 0; i < allThreads.size(); i++){
            if(!(allThreads.get(i).isAlive())){
                try {
                    Thread t = allThreads.get(i);
                    System.out.println("--Thread " + t.getId() + " Done--");
                    allThreads.remove(i);
                    t.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                System.out.println("~~Thread " + allThreads.get(i).getId() + " Not Done~~");
            }
        }
    }
}

public void run() {
    System.out.println("here");

    Thread t = Thread.currentThread();
    if (empty) { 
        System.out.println("empty means go");
        empty = false; 
        try {
            carCanGo.acquire();
            drive(randomGen.nextInt(100), t);
            clkUp.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } 
    }else { 
        Random randomGen = new Random();
        int randomNum = randomGen.nextInt(3);
        int streetNum = randomNum;
        streets.get(streetNum).add(t);
        System.out.println(t.getId() + " | " + streetNum + " | " + randomNum);

        // wait for someone to signal that it is street[i]’s turn to go 
        boolean spin = true;
        while(spin){
            if(t==streets.get(streetNum).peek()){
                spin = false;
            }
        }

        try {
            carCanGo.acquire();
            drive(streetNum, t);
            clkUp.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    } 
}

代码被删除,因为它已知有效(drive()和newCarsArrive(),可以根据请求重新添加)

在Main中,我们在clkUp上获取(),然后在carCanGo上获得release()。 在Run()中,我们在carCanGo上有acquire(),然后在clkUp上有release()。 当一个信号量被初始化为1而另一个信号量被初始化为0时,为什么这不起作用?

0 个答案:

没有答案