我正在尝试编写一个具有多个线程的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();
}
}
}
正如您所看到的,对于我正在创建的每个孩子,我将这些变量作为参数传递。总而言之,这是分配这些变量的正确方法吗?任何想法将不胜感激。提前谢谢!
答案 0 :(得分:3)
我认为设计很好,因为每个线程都应该有一个所需变量的副本。
你说:
例如,我可以使用map.putIfAbsent()使操作以原子方式执行
但这并不能使你的地图线程安全,因为有人可以在其上调用其他内容。
答案 1 :(得分:2)
嗯,这不是万无一失的。阅读ConcurrentHashMap文档中的所有caveats,例如 -
&#34;聚合状态方法的结果,包括size,isEmpty和 containsValue通常仅在未经历地图时有用 其他线程中的并发更新。&#34;
如果这些限制是可以接受的,那么你所拥有的就是好的。否则,您将需要自己的锁定方案来管理访问。
它可能像synchronized(sharedLockingObject)
那样简单,也可能像ReentrantReadWriteLock那样复杂。