2014-07-01 48 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