访问来自不同类的私有访问变量数据

时间:2013-08-02 10:38:18

标签: java

我的Project中有这个Thread,它不断地接受新的符号

public class StreamThread extends Thread {
    private Set<String> allSymbolSet = new HashSet<String>(Arrays.asList("USBC", "TCSD", "PCLJ"));
    private PriorityBlockingQueue<String> priorityBlocking = new PriorityBlockingQueue<String>();

    public void addSymbols(String str) {
        if (str != null) {
            priorityBlocking.add(str);
        }
    }

    public void run() {
        while (true) {
            try {
                while (priorityBlocking.peek() != null) {
                    String symbol = priorityBlocking.poll();
                    allSymbolSet.add(symbol);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

我的问题是,我想从另一个类

访问变量allSymbolSet

从anoter类访问名为allSymbolSet的变量的最佳方法是什么,为此我有两个选择

  1. 将allSymbolSet的访问说明符从private修改为默认值。

  2. 编写一个获取的方法,以便返回集

  3. 请建议我,在这种情况下会有什么好办法?

4 个答案:

答案 0 :(得分:3)

最佳方法是getter方法并同步对象allSymbolSet的访问,如下所示:

public Set<String> getAllSymbolSet() {
    synchronized(allSymbolSet) {
        return allSymbolSet;
    }
}

并同步对线程内allSymbolSet的访问权限。

答案 1 :(得分:2)

一些评论:

  • 如果您将集合设置为非私有,则某些代码可能会(错误或故意)修改它,这可能会导致StreamThread类中的行为不一致。不要那样做。
  • 提供简单的吸气剂并不能解决上述问题。更喜欢退回你的套装副本。
  • 在多线程环境中尽可能使变量成为最终 - 它解决了许多线程安全问题。
  • 首选实现Runnable而不是扩展Thread
  • 您需要同步对您的设置(读取和写入)的所有访问,例如使用synchronizedSet或更好地包装ConcurrentHashMap,这通常可以提供更好的性能。
  • 而不是peek + poll您可以从队列中take

所以你的最后一堂课看起来像:

public class StreamTask implements Runnable {

    private final Set<String> allSymbolSet;
    private final PriorityBlockingQueue<String> priorityBlocking = new PriorityBlockingQueue<String>();

    public StreamTask() {
         String[] symbols = {"USBC", "TCSD", "PCLJ"};
         //use a thread safe set, for example based on ConcurrentHashMap
         allSymbolSet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean> ());
         Collections.addAll(allSymbolSet, symbols);
    }

    public void addSymbols(String str) {
        if (str != null) {
            priorityBlocking.add(str);
        }
    }

    public Set<String> getSymbols() {
        return new HashSet<> (allSymbolSet); //return a copy
    }

    public void run() {
        while (true) {
            try {
                allSymbolSet.add(priorityBlocking.take());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

最后,我可能会遗漏一些东西,但那个类看起来更简单了:

public class StreamTask {

    private final Set<String> allSymbolSet;

    public StreamTask() {
         String[] symbols = {"USBC", "TCSD", "PCLJ"};
         //use a thread safe set, for example based on ConcurrentHashMap
         allSymbolSet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean> ());
         Collections.addAll(allSymbolSet, symbols);
    }

    public void addSymbols(String str) {
        if (str != null) {
            allSymbolSet.add(str);
        }
    }

    public Set<String> getSymbols() {
        return new HashSet<> (allSymbolSet); //return a copy
    }
}

答案 2 :(得分:0)

更好的方法是方法2.编写一个getter方法。如果要允许设置值,请稍后使用setter。然后你的数据将被封装。

答案 3 :(得分:0)

编写一个get方法,该方法应该返回Set。,使用此私有保留私有,您也可以使用同一类的Object从外部访问它。