2012-01-07 4 views
0
私は「読者と作家」問題を解決するプログラムを書くように頼まれた

でロックされたので、私はやってしまいました。残念ながらStack.peek()のいくつかの問題のためにスタックされています。以下のように、Thread-0はRUNNABLEですが、Bibliotekaオブジェクトをロックするので、Thread-2は処理を進めません。ロックされていないのは、何らかの理由で同期ブロックのif条件に固執しているからです。私の疑問は、java.util.Stackクラスが正しくロードされないということでした。しかし、私は本当に言うことができないと私はインターネット上で満足のいく答えを見つけることができませんでした。ですから、私の質問は、これまでに何かに会ったことがありますか?そのようなことについて私が読むことができる解決策や情報源を知っていますか?以下では、jstackが私に投げたものと関連するコードを載せます。スレッドはjava.util.Stackを

"Thread-2" prio=6 tid=0x03a00400 nid=0x1128 waiting for monitor entry [0x0371f00 0] 
java.lang.Thread.State: BLOCKED (on object monitor) 
     at Biblioteka.wejdzDoKolejki(Biblioteka.java:120) 
     - waiting to lock <0x290093d8> (a Biblioteka) 
     at Czytelnik.run(Czytelnik.java:37) 

"Thread-0" prio=6 tid=0x0130f000 nid=0x1294 runnable [0x0398f000] 
java.lang.Thread.State: RUNNABLE at java.util.Stack.peek(Unknown Source) 
     - locked <0x29009448> (a java.util.Stack) 
     at Biblioteka.run(Biblioteka.java:62) 
     - locked <0x290093d8> (a Biblioteka) 

import java.util.Stack; 
import java.util.concurrent.PriorityBlockingQueue; 

public class Biblioteka extends Thread{ 
    private Stack<Klient> wBibliotece; 
    private PriorityBlockingQueue<Klient> kolejka; 
    private int ksiazka; 

    public Biblioteka(){ 
     wBibliotece = new Stack<Klient>(); 
     kolejka = new PriorityBlockingQueue<Klient>(); 
     ksiazka = 0; 
    } 
    public void test(){ 
     int id_pisarzy = 0; 
     int id_czytelnikow = 0; 
     Klient k; 
     Random rand = new Random(); 
     Random zlote_mysli = new Random(); 
     while(true){ 
     try{ 
      Thread.sleep((long)(Math.random()*1000)); 
      if(rand.nextInt(10) > 5){ 
       id_pisarzy++; 
       new Pisarz("Pisarczyk #" + id_pisarzy, this, zlote_mysli.nextInt(1000)).start(); 
      } 
      else{ 
       id_czytelnikow++; 
       new Czytelnik("Czytacz #" + id_czytelnikow, this).start(); 
      } 
      if(rand.nextInt(10) > 3){ 
       synchronized(this){ 
        if(!wBibliotece.isEmpty()){ 
         try{ 
         if(wBibliotece.peek().kto() == "Pisarz") 
           Thread.sleep(1000); 
         }catch(InterruptedException e){ 
          e.printStackTrace(); 
         } 
         k = wBibliotece.pop(); 
         System.out.println("Z biblioteki wychodzi: " + k.kto() + " " + k.naImie()); 
         if(k.kto() == "Pisarz") 
          notify(); 
         } 
        else 
         notify(); 
       } 
      } 
     } 
     catch(Throwable e){ 
      e.printStackTrace(); 
     } 
     } 
    } 
    public void run(){ 
     Klient k; 
     while(true){ 
      synchronized(this){ 
      //Dopóki ktoś jest w bibliotece to pracuje 
       while(!wBibliotece.isEmpty()){ 
       //Jeżeli w bibliotece jest Pisarz to czekam aż wyjdzie 
        while(!wBibliotece.isEmpty() && wBibliotece.peek().kto() == "Pisarz"){ 
         try{ 
          System.out.println("not Working"); 
          wait(); 
         } 
         catch (InterruptedException e){ 
          e.printStackTrace(); 
         } 
        } 
       //Sprawdzam czy w kolejce jest pisarz 
        if(!kolejka.isEmpty()){ 
         while(!wBibliotece.isEmpty() && wBibliotece.peek().kto() == "Czytelnik" && !kolejka.isEmpty() && kolejka.peek().kto() == "Pisarz"){ 
          try{ 
           wait(); 
          } 
          catch(InterruptedException e){ 
           e.printStackTrace(); 
          } 
         } 
         k = kolejka.poll(); 
         wBibliotece.push(k); 
         System.out.println("Do biblioteki wchodzi: " + k.kto()+ " " + k.naImie()); 
         k.dziergaj(); 
        } 
       } 
       try{ 
        while(wBibliotece.isEmpty() && kolejka.isEmpty()) 
        { 
         try{ 
          wait(); 
         } 
         catch(InterruptedException e){ 
          e.printStackTrace(); 
         } 
        } 
        k = kolejka.poll(); 
        wBibliotece.push(k);   //i daje ją do biblioteki 
        System.out.println("Do biblioteki wchodzi: " + k.kto() + " " + k.naImie()); 
        k.dziergaj(); 
       } 
       catch(Throwable e){ 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

    public int czytaj(){ 
     return ksiazka; 
    } 

    public void pisz(int ksiazka){ 
     this.ksiazka = ksiazka; 
    } 

    public void wejdzDoKolejki(Klient k){ 
     kolejka.add(k); 
     System.out.println("Do kolejki wchodzi: " + k.kto() + " " + k.naImie()); 
     synchronized(this){ 
      notify(); 
     } 
    } 
} 
+2

ない[SSCCE](http://sscce.org/)私は自分のコードを通り抜けたので – Lion

答えて

1

私は、コード全体を通過しませんでしたが、私の知る限り見るように、ロックのための潜在的な場所がたくさんあります。同期ステートメントには十分注意してください。そして、すべてのStack方法が​​であることを念頭に置いています。可能であれば、Dequeの実装(例:ArrayDeque)を使用してください。

+0

は、あなたがしてくれロックのためにその潜在的な場所のいずれかを指すことができます本当に注意深く、私は可能性のあるスレッドスイッチのすべてをシミュレートしようと分析しました。しかし、私は完全にここで理解できないことができる唯一のことは、その行です: 'java.lang.Thread.State:java.util.Stack.peek(不明なソース)でRUNNABLEは - (java.util.Stackを)<0x29009448>をロック' あなたはそれが何を意味して私を説明することができますか? java.util.Stackでロックされている –

3

ロックを保持しながら、あなたが眠っています。一時停止するより良い方法は、待機を呼び出すことです()

synchronized(this){ 
    if(!wBibliotece.isEmpty()){ 
     try{ 
     if("Pisarz".equals(wBibliotece.peek().kto())) 
       wait(1000); // releases the lock while waiting. 
関連する問題