我们正在开发一个应用程序,其中一组对象可以通过接收来自 3 个不同来源的消息来影响。每条消息(来自任何来源)都有一个对象作为其目标。每个消息接收者都将在自己的线程上运行。
我们希望消息的处理(接收后)尽可能高速,因此针对目标对象的消息处理将由线程池中的另一个线程完成。消息的处理将比读取/接收来自发件人的消息花费更长的时间。
我在想,如果池中的每个线程只专用于一组特定的对象,它会更快,例如:
Thread1 -> objects named A-L
Thread2 -> objects named M-Z
每组对象(或线程)都有专门的消息队列等待处理。
我的假设是,如果唯一需要的线程同步是在每个接收线程和一个处理线程之间,在需要将消息放入阻塞队列的持续时间内,它将比随机分配工作线程更快处理消息(在这种情况下,可能有 2 个不同的线程处理同一对象的消息)。
我的问题实际上分为两部分:
人们是否同意专用工作线程的假设 对于一组特定的对象是更好/更快的方法吗?
假设这是一种更好的方法,请使用现有的 Java 线程池 类有办法支持这个吗?还是需要我们编码 我们自己的 ThreadPool 实现?
感谢您提供的任何建议。
最佳答案
[Is] dedicating worker threads to a particular set of objects is a better/faster approach?
我假设总体目标是尝试最大化这些入站消息的并发处理。您有来自 3 个源的接收器,它们需要将消息放入一个将得到最佳处理的池中。因为来自 3 个源中任何一个的消息都可能处理相同的目标对象,不能被同时处理,所以您希望以某种方式划分您的消息,以便它们可以被并发处理,但前提是它们不能被同时处理引用相同的目标对象。
我会在你的目标对象上实现 hashCode() 方法(也许只是 name.hashCode()),然后使用该值将对象放入数组中BlockingQueue,每个都有一个线程使用它们。使用 Executors.newSingleThreadExecutor() 数组就可以了。通过队列数修改哈希值模式并将其放入该队列。您需要将处理器的数量预定义为最大值。取决于处理的 CPU 密集程度。
所以类似下面的代码应该可以工作:
private static final int NUM_PROCESSING_QUEUES = 6;
...
ExecutorService[] pools = new ExecutorService[NUM_PROCESSING_QUEUES];
for (int i = 0; i < pools.length; i++) {
pools[i] = Executors.newSingleThreadExecutor();
}
...
// receiver loop:
while (true) {
Message message = receiveMessage();
int hash = Math.abs(message.hashCode());
// put each message in the appropriate pool based on its hash
// this assumes message is runnable
pools[hash % pools.length].submit(message);
}
此机制的好处之一是您可以限制有关目标对象的同步。您知道同一个目标对象只能由单个线程更新。
Do people agree with the assumption that dedicating worker threads to a particular set of objects is a better/faster approach?
是的。这似乎是获得最佳并发性的正确方法。
Assuming this is a better approach, do the existing Java ThreadPool classes have a way to support this? Or does it require us coding our own ThreadPool implementation?
我不知道有任何线程池可以完成此任务。不过,我不会编写您自己的实现。就像上面的代码概述一样使用它们。
关于java - 有没有办法确保将线程分配给指定的一组对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13348592/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat