2014-07-01 86 views
-1

我是Java的初學者。我已經寫了這個簡單的代碼,它接受來自用戶的整數數據並將它推入堆棧。線程不斷檢查堆棧的大小是否爲== 3.一旦堆棧達到此大小,線程將從堆棧彈出元素。我知道堆棧不同步。因此我使用了Collection.Synchronized方法來同步它。如何同步堆棧?

該實施是否可行?

import java.util.Collections; 
import java.util.Scanner; 
import java.util.Stack; 

public class StackSyncronisation<Item> extends Thread{ 
    private Stack<Item> s1; 

    public StackSyncronisation(){ 
     s1=new Stack<Item>(); 
     Collections.synchronizedList(s1); 
    } 

public void run(){ 

     //System.out.println("Inside run method"); 
     while(true){ 

      if(s1.size()==3){ 
       { 
       while(!s1.isEmpty()){ 

        // Poping out 
        System.out.println("Poping out from Stack"); 
        s1.pop(); 

         } 
       } 

      } 

     } 

    } 

public void push(Item d){ 


    s1.push(d); 

} 


    public static void main(String[]argc){ 


     StackSyncronisation<Integer> x1=new StackSyncronisation<Integer>(); 

     x1.start(); 


Scanner in=new Scanner(System.in); 

     while(true){ 

      System.out.println("Enter 1:Push"); 
      //in.nextInt(); 

      switch (in.nextInt()) { 
      case 1: x1.push(in.nextInt());    
        break; 

      default: 
       break; 
      } 



     } 


    } 



} 
+1

「此實施是否有效?」 - 寫一些測試.... –

回答

3

Java棧同步。Stack延伸Vector,它是同步的。兩者都是半棄用的。建議使用ArrayDeque代替StackArrayList代替Vector。但是,既然你在這種情況下想要同步,也許你應該堅持Stack

這並不做任何事情:

Collections.synchronizedList(s1); 

Collections.synchronizedList返回集合的包裝版本,但是因爲你不保存返回值它實際上並沒有做任何事情,但浪費資源。 s1仍然指向展開的堆棧,但由於Stack已經同步,所以這可能很好。您只需撥打電話synchronizedList即可。

從同步的角度來看,我認爲你發佈的內容應該可以正常工作。看起來你會有一個或多個線程推送到堆棧,但只有一個線程從堆棧彈出。在這種情況下,當您嘗試使用pop()時,可以保證s1不會爲空。如果你有多個線程從棧中彈出,那麼這個代碼是不安全的,因爲噸檢查size()==3和嘗試pop()之間可能會發生噸。

+0

,感謝您的快速回復快速的問題:所以線程將鎖定棧,直到它彈出所有元素或只是一個元素? – user3792088

+0

@ user3792088 - 同步在棧內。當您在堆棧上調用某個方法時,該方法調用會「自動」發生,但只要您開始討論兩個或更多個調用,則所有投注都將關閉。你需要單獨的同步來處理。 – DaoWen