Java并发 - 最好有一个带有锁的线程列表或一个带有请求列表的线程?

Posted

技术标签:

【中文标题】Java并发 - 最好有一个带有锁的线程列表或一个带有请求列表的线程?【英文标题】:Java concurrency - Better to have list of threads with lock or one thread with list of requests? 【发布时间】:2014-01-15 21:57:43 【问题描述】:

我刚开始接触并发,所以如果我问一些明显/愚蠢的事情,请耐心等待。我正试图采取第一步来改造我必须利用 Java 货币的模型。在不深入细节的情况下,我有一部分模型加载了一些文件,然后当给定请求时,它会返回文件上的一些相应数据。我的挑战是现在让它在它自己的线程上运行,这样虽然它仍然一次只处理一个请求,但它可以将其他部分代码在它们自己的线程上运行的请求排队。

在尝试通过 jenkov.com 上的优秀教程自学并发性之后,我使用了我学到的东西,基本上创建了一个很像 BlockingQueue 的东西,其中有一个对象充当锁,请求作为排队的线程进入,并且当当前线程完成处理时,它会为下一个线程解锁。因此线程不断被创建、等待、启动,然后最终被销毁,因为每个请求都是一个新线程。

我现在想的是,它更像是我最初想象的那样,只有一个线程等待指令,然后处理这些指令。因此,请求不是作为线程进来的,而是有一些单一的线程等待直到它有一个请求,处理它,处理任何其他排队的请求,如果没有更多的请求,则再次等待。 (假定的)优势是请求作为变量/指导者进来,并且线程不会被不断地创建/销毁。

所以问题是将它重写为更像那样有优势吗?我知道创建/销毁线程可能不会产生大量开销(只要我使用等待/通知功能而不是说忙等待),但这是一种必须运行数百万的模型在这种情况下,有时迭代甚至边际收益会成倍增加。

【问题讨论】:

你应该阅读"Java Concurrency in Practice"。 谢谢,我一定会把它添加到我的购物车中。感觉就像我已经进入了一个完整的“另一个层次,所以一本好书肯定会受到赞赏。 【参考方案1】:

不要创建一堆线程;使用 ExecutorService,使用 SingleThreadExecutor 对其进行初始化,并为您的用户(客户端类)提供他们可以调用以将作业提交给 Executor 的 API。只需替换(或专门化)您的执行者,这将为您提供很多未来的灵活性。

这是对评论的第二次投票:去阅读 Brian Goetz 的“Java Concurrency In Practice” - 我不能高度推荐这个。

在您等待图书送达时:

http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html http://tutorials.jenkov.com/java-util-concurrent/executorservice.html

【讨论】:

我认为你的意思是线程池执行器。单线程执行器只使用一个线程! 太棒了,谢谢,这看起来像我更仔细地描绘的那样。我一定会订购这本书。 @GiovanniBotta 实际上,我的意思是 SingleThreadExecutor;他明确表示他希望作业一次运行一个,出于某种原因:My challenge is to make this run on it's own thread now, so that while it still only processes one request at a time, it can queue up requests made other parts of the code running on their own threads.——但通过使用执行器框架,他稍后可以通过单行代码更改切换到线程池执行器并获得更多并发性,如果合适的话。 (听起来他在寻找更智能的作业排队框架,而不是更多的并发) 对不起,我错过了那句话! 目前我想避免让多个线程同时处理同一个文件以避免潜在的并发症。所以最初可能不会有太多的速度提升,但这是我需要在这个特定部分完成的事情,然后我才能让其他组件根据当前构建的性质来利用并发性。但不是其他话题,如果不深入不必要的深度,很难解释。我已经可以想象如何使用单人和池执行器。谢谢!

以上是关于Java并发 - 最好有一个带有锁的线程列表或一个带有请求列表的线程?的主要内容,如果未能解决你的问题,请参考以下文章

关于Java中锁的总结

Java并发机制及锁的实现原理

Java并发编程——锁

Java并发编程:线程和锁的使用与解析

java中悲观锁和乐观锁的区别

Java并发编程:可重入内置锁