java信号量问题

时间:2011-07-03 05:52:16

标签: java semaphore

我是java的新手,我只是试图通过以下示例来了解这种语言。任何人都可以告诉为什么以下程序只显示:

     calling prod
     calling cons

import java.util.concurrent.*;

public class Trial5 {
    static public void main(String[] arg){
            new Prod();
            new Cons();
    }
}

class Q {
    static Semaphore semc = new Semaphore(0);
    static Semaphore semp  = new Semaphore(1);
    static int q[];
}

class Cons implements Runnable{
    Thread t;
    Cons () {
            System.out.println("calling cons");
            Thread t = new Thread();
            t.start();
    }
    public void run () {
            System.out.println("Running semc");
            try {
                System.out.println ("Waiting for Data.Acquiring semc");
                Q.semc.acquire ();
                if(Q.q[0] != 0) {
                    System.out.println(Q.q[0]);
                    Q.q[0] = 0;
                } else {
                    wait ();
                }
                System.out.println ("Releasing semc");
                Q.semc.release ();
            }
            catch (Exception e) {
            System.out.println (e.getMessage());
         }
     }
 }

 class Prod implements Runnable {
      Thread t;
      Prod () {
           System.out.println ("calling prod");
           t = new Thread ();
           t.start ();
      }
      public void run() {
           System.out.println ("running semp");
           try {
                System.out.println ("Waiting for Data.Acquiring semp");
                Q.semp.acquire ();
                if (Q.q[0] == 0) {
                     System.out.println ("setting value semp");
                     Q.q[0] = 10;
                } else {
                     Thread.sleep(100);
                }
                System.out.println ("Releasing semp");
                Q.semp.release ();
           }
           catch (Exception e) {
                System.out.println (e.getMessage());
           }    
      }
 }

3 个答案:

答案 0 :(得分:2)

你的问题不在于信号量,而在于你的线程。您的run方法没有执行,因为您正在实例化Thread的新实例,这些实例不知道您创建的类并运行它们而不是对您创建的类执行任何操作。因此,您的运行方法永远不会被调用。

具体来说,这样的行:

Thread t = new Thread();
t.start();

没有引用它们包含的类。它们只是创建一个新的Thread对象,它只有默认的run方法,然后启动它。

This site提供了如何运行Threads的示例(通过扩展Thread或实现Runnable)。但是,您将不得不重新构建一些代码以使其工作。虽然可以简单地将行更改为读取

Thread t = new Thread(this);

这是一个坏主意,因为在构造函数仍在运行时,您将对象作为值传递。更好的想法是让你的main方法构造每个对象,然后使用它们来启动运行的线程。

答案 1 :(得分:1)

此外:

  1. 始终在a中使用信号量 try-finally阻止。无论如何 发生在你总是释放 信号量,否则就是死锁 必然会发生。
  2. 你正在调用'wait()'(这是Runnable(继承自Object)实例的方法),但你不能,因为你没有拥有锁。有关详情,请参阅Monitor
  3. Thread.sleep(100)实际上抛出InterruptedException:捕获它并重新中断线程,因为当抛出InterruptedException时,中断标志被清除。有关此主题的更多信息,请参阅Dealing with InterruptedException

答案 2 :(得分:0)

你需要做

t = new Prod();

t= new Cons();

见此处以供进一步参考: http://www.exampledepot.com/egs/java.lang/BasicThread.html