我试图编写一个解决scheme,在这个解决scheme中,一个线程产生可以并行执行的I / O密集型任务。 每个任务都有重要的内存数据。 所以我希望能够限制暂时的任务数量。 如果我这样创buildThreadPoolExecutor: ThreadPoolExecutor executor = new ThreadPoolExecutor(numWorkerThreads, numWorkerThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(maxQueue)); 然后executor.submit(callable)抛出RejectedExecutionException当队列填满和所有线程已经忙。 我可以做些什么来使executor.submit(callable)块当队列已满,所有线程都忙? 编辑 :我试过这个 : executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); 它有点达到我想达到的效果,但以一种不雅的方式(基本上拒绝的线程在调用线程中运行,因此阻止调用线程提交更多)。 编辑:( 5年后提问) 对于阅读这个问题及其答案的任何人,请不要把接受的答案作为一个正确的解决scheme。 请阅读所有的答案和评论。
我们将使用Clojure编写一个并发程序,该程序将从大量传入的邮件中提取关键字,这些邮件将与数据库进行交叉检查。 我的一个队友build议使用Erlang编写这个程序。 在这里,我想说明一些我对函数式编程的新东西,所以我有点怀疑clojure是编写这个程序的好select,还是Erlang更适合。
Haskell是function性和纯粹的,所以基本上它具有编译器能够处理隐式并行所需的所有属性。 考虑这个微不足道的例子: f = do a <- Just 1 b <- Just $ Just 2 — ^ The above line does not utilize an `a` variable, so it can be safely — executed in parallel with the preceding line c <- b — ^ The above line references a `b` variable, so it can only […]
在mongodb文档中,它说: 从版本2.2开始,对于大多数读写操作,MongoDB基于每个数据库实现locking。 一些全球性操作,通常是涉及多个数据库的短期操作,仍然需要全局“实例”locking。 在2.2之前,每个mongod实例只有一个“全局”锁。 这是否意味着,在我所拥有的情况下,例如,从networking上运行的不同应用程序连接到mongodb:// localhost / test – 只能有一次写入? 还是只是每个连接? IOW:是每个连接,还是整个/testing数据库在写入时被locking?
使用Condition接口/实现比传统的等待通知机制有什么优势? 在这里我引用Doug Lea写的评论: 将对象监视器方法(wait,notify和notifyAll)的条件因素排除在不同的对象之外,使每个对象具有多个等待集,并将它们与使用任意Lock实现相结合。 在Lock取代了同步方法和语句的使用的情况下,一个Condition取代了Object监视器方法的使用。 我看到这是一个更加面向对象的实现等待/通知机制的方式。 但是有没有比前者好的优势?
我有很less的asynchronous任务正在运行,我需要等到至less有一个任务完成(将来可能需要等待N个任务完成)。 目前他们被提呈为未来,所以我需要类似的东西 /** * Blocks current thread until one of specified futures is done and returns it. */ public static <T> Future<T> waitForAny(Collection<Future<T>> futures) throws AllFuturesFailedException 有没有这样的事情? 或者任何类似的,对于未来不是必需的。 目前我通过收集期货循环,检查是否完成,然后睡一会儿再检查。 这看起来不是最好的解决scheme,因为如果我长时间睡眠,那么不必要的延迟就会增加,如果我睡了很短的时间就会影响性能。 我可以尝试使用 new CountDownLatch(1) 并在任务完成时减less倒计时 countdown.await() ,但是我发现只有我控制Future的创造才有可能。 这是可能的,但是需要系统重新devise,因为目前创build任务的逻辑(发送Callable到ExecutorService)与决定等待哪个Future是分开的。 我也可以覆盖 <T> RunnableFuture<T> AbstractExecutorService.newTaskFor(Callable<T> callable) 并创buildRunnableFuture的自定义实现,具有附加侦听器以在任务完成时得到通知的能力,然后将这个侦听器附加到需要的任务并使用CountDownLatch,但这意味着我必须重写newTaskFor对于我使用的每个ExecutorService – 并且可能会有实现不扩展AbstractExecutorService。 我也可以尝试包装给定ExecutorService出于同样的目的,但是我必须装饰所有产生期货的方法。 所有这些解决scheme可能工作,但似乎很不自然。 它看起来像我缺less一些简单的东西,比如 WaitHandle.WaitAny(WaitHandle[] waitHandles) 在C#中。 有这样的问题有什么众所周知的解决scheme吗? 更新: 本来我根本没有进入未来的创造,所以没有优雅的解决scheme。 重新devise系统后,我有权访问未来创build,并能够添加countDownLatch.countdown()执行过程,然后我可以countDownLatch.await(),一切工作正常。 […]
在看Go和Erlang的并发方法时,我注意到它们都依赖于消息传递。 这种方法显然减轻了对复杂锁的需求,因为没有共享状态。 但是,考虑许多客户机需要对内存中的单个大型数据结构进行并行只读访问的情况 – 如后缀数组。 我的问题: 将使用共享状态更快,并使用更less的内存比消息传递,因为数据是只读的,只需要在一个单一的位置存在锁通常是不必要的? 在消息传递上下文中如何处理这个问题? 会不会有一个访问数据结构的进程,客户端只需要按顺序请求数据呢? 或者,如果可能的话,数据是否会被分块来创build多个处理大块的进程? 鉴于现代CPU和内存的架构,这两种解决scheme之间是否有很大的区别?即,多核可以共享内存是否可以被并行读取?这意味着没有任何硬件瓶颈,否则这两个解决scheme会大致执行相同的操作?
我正在阅读描述SyncRoot模式的ac#书。 表明 void doThis() { lock(this){ … } } void doThat() { lock(this){ … } } 并与SyncRoot模式进行比较: object syncRoot = new object(); void doThis() { lock(syncRoot ){ … } } void doThat() { lock(syncRoot){ … } } 不过,我不太了解这里的区别。 似乎在两种情况下,两种方法一次只能由一个线程访问。 本书描述了…因为实例的对象也可以用于从外部进行同步访问,并且不能控制这个表格的类本身,所以可以使用SyncRoot模式 Eh? “实例的对象”? 谁能告诉我上面两种方法的区别? 提前致谢
我有一个很大的JUnittesting套件,我很想同时运行所有的testing,原因有两个: 利用多个内核来更快地运行整个testing套件 希望能够检测到由于非线程安全的全局对象造成的一些错误 我认识到这将迫使我重构一些代码,使其线程安全,但我认为这是一件好事:-) 让JUnit同时运行所有testing的最好方法是什么?
在Tour 1.5网站发布之前的版本中 ,有一段代码看起来像这样。 package main import ( "fmt" "runtime" ) func say(s string) { for i := 0; i < 5; i++ { runtime.Gosched() fmt.Println(s) } } func main() { go say("world") say("hello") } 输出如下所示: hello world hello world hello world hello world hello 什么是困扰我的是,当runtime.Gosched()被删除,程序不再打印“世界”。 hello hello hello hello hello 为什么? runtime.Gosched()如何影响执行?