与并发共享变量

时间:2016-12-21 03:42:35

标签: java multithreading concurrency

我正在尝试编写一个具有多个线程的Java程序。我有两个在启动时创建的变量。一个是AtomicBoolean,告诉整个程序何时关闭(即关闭客户端)。另一个变量是ConcurrentHashMap,它包含一组在启动时加载的命令。有些线程包含一个客户端可运行的,当客户端被接受时运行(每个客户端一个线程)。还有一个线程通过侦听外部更改(来自目录的新命令等)来更新HashMap的命令。

以下是代码:

class Program {
    /* ... other vars like ServerSocket, etc. */
    private final ConcurrentHashMap<String, String> mCommands;
    private final AtomicBoolean mIsListening;

    public static void main(String[] args) {
        Program prog = new Program();
        prog.loadCommands();
        prog.listen();
    }

    public Program() {
        mCommands = new ConcurrentHashMap<>();
        mIsListening = new AtomicBoolean(true);
        /* other initializations */
    }

    public void loadCommands() {
         /* Loads commands generated from a directory; updates mCommands, then... */
         new Thread(new CommandListenerRunnable(mCommands)).start();
    }

    public void listen() {
        /* accepting a new client from server socket */
        while (mIsListening.get()) {
            Socket client = ss.accept();
            new Thread(new ClientRunnable(client, mCommands, mIsListening)).start();
        }
    }
}

正如您所看到的,对于我正在创建的每个孩子,我将这些变量作为参数传递。总而言之,这是分配这些变量的正确方法吗?任何想法将不胜感激。提前谢谢!

2 个答案:

答案 0 :(得分:3)

我认为设计很好,因为每个线程都应该有一个所需变量的副本。

你说:

  

例如,我可以使用map.putIfAbsent()使操作以原子方式执行

但这并不能使你的地图线程安全,因为有人可以在其上调用其他内容。

答案 1 :(得分:2)

嗯,这不是万无一失的。阅读ConcurrentHashMap文档中的所有caveats,例如 -

  

&#34;聚合状态方法的结果,包括size,isEmpty和   containsValue通常仅在未经历地图时有用   其他线程中的并发更新。&#34;

如果这些限制是可以接受的,那么你所拥有的就是好的。否则,您将需要自己的锁定方案来管理访问。

它可能像synchronized(sharedLockingObject)那样简单,也可能像ReentrantReadWriteLock那样复杂。