Проблема с семафором Java - PullRequest
0 голосов
/ 03 июля 2011

Я новичок в 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 ]

2 голосов
/ 03 июля 2011

Ваша проблема не в семафоре, а в ваших темах.Ваш метод run не выполняется, потому что вы создаете новые экземпляры Thread, которые не имеют представления о классах, которые вы создали, и запускаете их, а не делаете что-либо с классами, которые вы создали.Таким образом, ваши методы запуска никогда не вызываются.

В частности, такие строки:

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

не имеют ссылки на классы, в которых они содержатся. Они просто создают новый объект Thread, которыйимеет только метод запуска по умолчанию и затем запускает его.

На этом сайте есть примеры того, как запускаются потоки (либо путем расширения потока, либо путем реализации Runnable).Однако вам придется немного реструктурировать свой код, чтобы он заработал.Хотя это может сработать, просто изменив строки на

Thread t = new Thread(this);

, это плохая идея, поскольку вы передаете объект как значение, пока его конструктор еще работает.Лучше было бы, чтобы ваш метод main создавал каждый объект, а затем использовал их для запуска запущенных потоков.

1 голос
/ 03 июля 2011

Кроме того:

  1. Всегда используйте семафоры в попробуйте наконец заблокировать. Так что бы ни бывает, вы всегда отпускаете семафор, иначе тупик обязательно произойдет.
  2. Вы вызываете 'wait ()' (который является методом экземпляра Runnable (унаследованного от Object)), но вы не можете, потому что у вас нет блокировки. Подробнее об этом см. Монитор
  3. Thread.sleep (100) фактически создает исключение InterruptedException: перехватывает его и повторно прерывает поток , поскольку флаг прерывания сбрасывается при возникновении исключения InterruptedException. Подробнее об этом см., Например, Работа с InterruptedException
0 голосов
/ 03 июля 2011

Вам нужно сделать

t = new Prod();

и

t= new Cons();

см. Здесь для дальнейшей справки: http://www.exampledepot.com/egs/java.lang/BasicThread.html

...