2017-09-15 95 views
1

我不明白我的錯誤,我會描述它,然後我會發布我的代碼。 從main()我想運行3個線程(每個線程包含3個女性的循環)。 我有一種方法可以打印出每個進入洗手間的女人和每個出門的女人。我想要使用鎖,因此每個線程中的每個女人都會在下一個線程發生之前寫入每一個線程。輸出應該是這樣的: 女人0進入浴室 女人0離開浴室 女人1進入浴室 女人1分離開浴室 女人2進入浴室 女人2分離開浴室 ,然後2倍爲每個線程。 我的問題是,只有一個線程正在寫入,2個沒有達到我釋放鎖之後仍在等待的鎖。 這裏是我的代碼:(衛浴類)3線程鎖定

private Lock lockW=new ReentrantLock(); 
public int women_present; 


public BathRoom(){ 
    women_present=0;//empty at start 
} 



public void woman_wants_to_enter (int i) { 
    lockW.lock(); 

    women_present++; 
    System.out.println ("Woman " + i + " enters bathroom ");  } 
public void woman_leaves (int i) { 
    try { 
     Thread.sleep (1000); 

    }catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println ("Woman " + i + " exits bathroom "); 
    if((women_present%3)==0){ 
     women_present=0; 
     lockW.unlock(); 
    } } 

這是女性類:

private int i; /* This identifies the woman. */ 
    private BathRoom bathroom; 

public Woman (BathRoom bathroom,int i) { 
     this.i = i; 
     this.bathroom = bathroom; 
    } 

public void run() { 
for (int i = 0; i < 3; i++) { 
    try { 
      Thread.sleep ((long) (500 * Math.random())); 
     }catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     bathroom.woman_wants_to_enter (i); 
     bathroom.woman_leaves (i); 
     } 
    }} 
+0

'if((women_present%3)== 0){'test。如果數字*已經爲零,那麼你只能解鎖,讓無意義的'%3'放在一邊......最後,你根本不需要'women_present'計數器。你爲每個'woman_wants_to_enter'調用'lock()',因此,你必須爲每個'woman_leaves'調用'unlock'。然後,你已經完成了。 – Holger

+0

正如我所說,每個線程包含3名女性。 – demianr

+0

我給出的問題是在每個線程完成後解鎖,而不是每個女人在thread.you可以想到它像每個線程是一組3個女人。 – demianr

回答

1

我冒昧地修改代碼:

package stackoverflow; 

import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

class BathRoom { 
    private Lock lockW=new ReentrantLock(); 
    private Condition c1=lockW.newCondition(); 
    public int women_present; 


    public BathRoom(){ 
     women_present=0;//empty at start 
    } 



    public void woman_wants_to_enter (int i) { 
     lockW.lock(); 
     while(women_present!=i) 
      try { 
       c1.await(); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


     System.out.println ("Woman " + i + " enters bathroom ");  } 
    public void woman_leaves (int i) { 
     try { 
      Thread.sleep (1000); 

     }catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println ("Woman " + i + " exits bathroom "); 
     women_present++;  
     if(women_present==3){ 
      women_present=0; 
     } 
     c1.signal(); 
     lockW.unlock(); 
} 
} 
class Woman implements Runnable{ 
    private int i; /* This identifies the woman. */ 
     private BathRoom bathroom; 

    public Woman (BathRoom bathroom,int i) { 
      this.i = i; 
      this.bathroom = bathroom; 
     } 

    public void run() { 
    for (int i = 0; i < 3; i++) { 
     try { 
       Thread.sleep ((long) (500 * Math.random())); 
      }catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      bathroom.woman_wants_to_enter (i); 
      bathroom.woman_leaves (i); 
      } 
     } 
    } 

public class testdummy { 

    public static void main(String[] args) { 

     BathRoom b=new BathRoom(); 

     Woman w0=new Woman(b, 0); 
     Woman w1=new Woman(b, 1); 
     Woman w2=new Woman(b, 2); 

     Thread A=new Thread(w0); 
     Thread B=new Thread(w1); 
     Thread C=new Thread(w2); 

     A.start(); 
     B.start(); 
     C.start(); 



    } 

} 

我剛纔所用條件對象的線程同步ACCE ss的方法,它不完美,但它的作品,希望它會給你一個更好的方法的想法。

+0

lock.unlock()應該是理想的最終塊內 – Roshan

+0

賓果,非常感謝你 – demianr

+0

@demianr你可以upvote,如果你覺得這個答案適合你 – Roshan

0

第一線 在woman_wants_to_enter(), 線程aquires鎖(),所以繼續。 woman_present被設置爲1

在woman_leaves(),woman_present仍爲1 如果(1個模3是1),以便解鎖不叫

第二線程進入woman_wants_to_enter(),但正在等待鎖定

+0

在每個線程中有3個女人(在運行方法中的循環),只有在那之後我想釋放鎖定讓其他線程(與3個女人在一起) – demianr

+0

我不想釋放每個女人,但每3(數字每個線程中的女性) – demianr