信号量不按预期工作,它被锁定

时间:2014-03-10 11:27:20

标签: multithreading semaphore

我使用信号量进行线程通信我有两个线程,一个是OddThread,另一个是EvenThread,我打印值从1到10 OddThread将只打印1到10之间的奇数,而EvenThread线程只打印1之间的偶数因为我已经使用信号量来让线程正常通信。实际上发生的事情是OddThread只打印1而EvenThread只打印2然后两者都停止了。我并不知道实际发生的事情。任何人都建议。

   public class ThreadProducerConsumerSemaphore {


/**
 * @param args
 */
public static void main(String[] args) {
    Semaphore p = new Semaphore(1);
     Semaphore c = new Semaphore(0);
     OddThread producer = new OddThread(p, c);
     EvenThread consumer = new EvenThread(p, c);
    Thread t1 = new Thread(producer, "Thread producer");
    Thread t2 = new Thread(consumer, "Thread consumer");
    t1.start();
    t2.start();
  }
}

 class OddThread implements Runnable {
Semaphore p;
Semaphore c;

public OddThread(Semaphore p, Semaphore c) {
    super();
    this.p = p;
    this.c = c;
}

int counter = 1;

@Override
public void run() {

    while (true) {
        try {
            p.acquire(1);
            System.out.println(Thread.currentThread().getName() + " "
                    + counter);
            if (counter == 10) {
                break;
            }
            counter++;
            c.release(1);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
 }

  class EvenThread implements Runnable {
Semaphore p;
Semaphore c;
int counter = 2;

public EvenThread(Semaphore p, Semaphore c) {
    super();
    this.p = p;
    this.c = c;
}

@Override
public void run() {

    while (true) {
        try {
            c.acquire(1);
            System.out.println(Thread.currentThread().getName() + " "
                    + counter);
            if (counter == 10) {
                break;
            }
            counter=counter+2;
            p.acquire(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

 }

3 个答案:

答案 0 :(得分:0)

你的代码不正确,甚至不对称。

p.acquire(1);
c.release(1);

c.acquire(1);
p.acquire(1);

答案 1 :(得分:0)

您的EvenThread.run方法同时获取cp,而不是释放其中一个。

但请注意,即使修复了代码,您的代码看起来也不会正常退出。考虑一下:两个线程在退出之前都不会释放信号量,因此其中一个线程将不可避免地被阻塞。

答案 2 :(得分:0)

这是你的问题:

    ............
    c.acquire(1);
    System.out.println(Thread.currentThread().getName() + " "
            + counter);
    if (counter == 10) {
        break;
    }
    counter=counter+2;
    p.acquire(1);   <--deadlock this has already been acquired by the other thread.
    ..............

你应该在这里释放p,以允许另一个线程继续;所以用p.release(1)替换我指示的行,它应该没问题。