Java读写锁定要求,具有来自不同线程的锁定和释放(Java read & write lock requirement, with lock and release from different threads)
我试图找到一个不那么笨重的Java并发问题的解决方案。
问题的关键在于,当仍有工作线程处于活动状态时,我需要对块进行关闭调用,但关键的方面是每个工作任务都是异步生成和完成的,因此保持和释放必须由不同的线程完成。 一旦他们的工作完成,我需要他们以某种方式向关闭线程发送信号。 只是为了让事情更有趣,工作线程不能互相阻塞,所以我不确定信号量在这个特定实例中的应用。
我有一个解决方案,我认为安全地完成了这项工作,但是我对Java并发工具的不熟悉使我认为可能有一个更容易或更优雅的模式。 在这方面的任何帮助将不胜感激。
这是我到目前为止所做的,除了评论之外相当稀疏:
final private ReentrantReadWriteLock shutdownLock = new ReentrantReadWriteLock(); volatile private int activeWorkerThreads; private boolean isShutdown; private void workerTask() { try { // Point A: Worker tasks mustn't block each other. shutdownLock.readLock().lock(); // Point B: I only want worker tasks to continue if the shutdown signal // hasn't already been received. if (isShutdown) return; activeWorkerThreads ++; // Point C: This async method call returns immediately, soon after which // we release our lock. The shutdown thread may then acquire the write lock // but we want it to continue blocking until all of the asynchronous tasks // have completed. executeAsynchronously(new Runnable() { @Override final public void run() { try { // Do stuff. } finally { // Point D: Release of shutdown thread loop, if there are no other // active worker tasks. activeWorkerThreads --; } } }); } finally { shutdownLock.readLock().unlock(); } } final public void shutdown() { try { // Point E: Shutdown thread must block while any worker threads // have breached Point A. shutdownLock.writeLock().lock(); isShutdown = true; // Point F: Is there a better way to wait for this signal? while (activeWorkerThreads > 0) ; // Do shutdown operation. } finally { shutdownLock.writeLock().unlock(); } }
预先感谢任何帮助!
拉斯
I'm trying to find a less clunky solution to a Java concurrency problem.
The gist of the problem is that I need a shutdown call to block while there are still worker threads active, but the crucial aspect is that the worker tasks are each spawned and completed asynchronously so the hold and release must be done by different threads. I need them to somehow send a signal to the shutdown thread once their work has completed. Just to make things more interesting, the worker threads cannot block each other so I'm unsure about the application of a Semaphore in this particular instance.
I have a solution which I think safely does the job, but my unfamiliarity with the Java concurrency utils leads me to think that there might be a much easier or more elegant pattern. Any help in this regard would be greatly appreciated.
Here's what I have so far, fairly sparse except for the comments:
final private ReentrantReadWriteLock shutdownLock = new ReentrantReadWriteLock(); volatile private int activeWorkerThreads; private boolean isShutdown; private void workerTask() { try { // Point A: Worker tasks mustn't block each other. shutdownLock.readLock().lock(); // Point B: I only want worker tasks to continue if the shutdown signal // hasn't already been received. if (isShutdown) return; activeWorkerThreads ++; // Point C: This async method call returns immediately, soon after which // we release our lock. The shutdown thread may then acquire the write lock // but we want it to continue blocking until all of the asynchronous tasks // have completed. executeAsynchronously(new Runnable() { @Override final public void run() { try { // Do stuff. } finally { // Point D: Release of shutdown thread loop, if there are no other // active worker tasks. activeWorkerThreads --; } } }); } finally { shutdownLock.readLock().unlock(); } } final public void shutdown() { try { // Point E: Shutdown thread must block while any worker threads // have breached Point A. shutdownLock.writeLock().lock(); isShutdown = true; // Point F: Is there a better way to wait for this signal? while (activeWorkerThreads > 0) ; // Do shutdown operation. } finally { shutdownLock.writeLock().unlock(); } }
Thanks in advance for any help!
Russ
原文:https://stackoverflow.com/questions/6921530
最满意答案
对于第一次编辑,我建议您将对象更改为其他形式
var object = { "10-10-2017": "Black friday", "11-09-2017": "Some holiday", "10-10-2017": "Fathers day" }
至
var object =[ {"date":"10-10-2017","value":"Black friday"}, {"date":"11-09-2017","value":"Some holiday"}, {"date":"10-10-2017","value":"Fathers day"} ]
如果这有助于你这里的工作解决方案
var object = [{date:"10-10-2017",value:"Black friday"},{date:"11-09-2017",value:"Some holiday"},{date:"10-10-2017",value:"Fathers day"}]; var output =[]; object.forEach(function(value) { var existing = output.filter(function(v, i) { return v.date == value.date; }); if (existing.length) { var existingIndex = output.indexOf(existing[0]); output[existingIndex].value += ' '+value.value } else { if (typeof value.value == 'string') value.value = value.value; output.push(value); } }); console.log(JSON.stringify(output)); //returns [{"date":"10-10-2017","value":"Black friday Fathers day"},{"date":"11-09-2017","value":"Some holiday"}]
For the first edit I suggest that you change your object into other form from
var object = { "10-10-2017": "Black friday", "11-09-2017": "Some holiday", "10-10-2017": "Fathers day" }
to
var object =[ {"date":"10-10-2017","value":"Black friday"}, {"date":"11-09-2017","value":"Some holiday"}, {"date":"10-10-2017","value":"Fathers day"} ]
If that helps you here's the working solution
var object = [{date:"10-10-2017",value:"Black friday"},{date:"11-09-2017",value:"Some holiday"},{date:"10-10-2017",value:"Fathers day"}]; var output =[]; object.forEach(function(value) { var existing = output.filter(function(v, i) { return v.date == value.date; }); if (existing.length) { var existingIndex = output.indexOf(existing[0]); output[existingIndex].value += ' '+value.value } else { if (typeof value.value == 'string') value.value = value.value; output.push(value); } }); console.log(JSON.stringify(output)); //returns [{"date":"10-10-2017","value":"Black friday Fathers day"},{"date":"11-09-2017","value":"Some holiday"}]
相关问答
更多-
不是原型方法,但可以使用Object.getPrototypeOf遍历原型链,然后获取每个对象的属性名称。 function logAllProperties(obj) { if (obj == null) return; // recursive approach console.log(Object.getOwnPropertyNames(obj)); logAllProperties(Object.getPrototypeOf(obj)); } logAllPropert ...
-
如何动态地合并两个JavaScript对象的属性?(How can I merge properties of two JavaScript objects dynamically?)[2023-03-16]
ECMAScript 2015(ES6)标准方法 /* For the case in question, you would do: */ Object.assign(obj1, obj2); /** There's no limit to the number of objects you can merge. * All objects get merged into the first object. * Only the object in the first argument is ... -
我只是在这里猜测,因为我在查看示例代码时遇到了问题,但我认为你想要默认值() : const result = _.defaults({ foo: true }, { foo: false, bar: true }); // ➜ { foo: true, bar: true } 这只会合并到尚不存在的属性中。 I'm just guessing here, because I'm having trouble following your sample code, but I think you want ...
-
将javascript对象(属性+值)合并到一个对象中(Merging javascript objects (properties+values) into one object)[2024-04-09]
你要问的是删除重复的对象,你使用深度相等的方法将副本定义为具有相同的值。 请参阅http://underscorejs.org/#isEqual以下是对列表进行重复数据删除的示例脚本。 它不是很优雅,但它有效: var objects = [ {"delta":["St.Louis"],"lambda":[],"amount":200000}, {"delta":["St.Louis"],"lambda":[],"amount":200000}, {"delta":["Different" ... -
你可以做到这一点,但请注意,如果一个属性也在b它将被覆盖。 function(a, b) { if (a && b) { for (var key in b) { if (b.hasOwnProperty(key)) { a[key] = b[key]; } } } return a; } You could do this, but note that a property in a will be overwritten if it' ...
-
类似的问题在这里问: nodeJS的深度扩展(如jQuery) 只需将接受的答案中的extend函数复制到项目中,以便在正确的范围内可用。 然后像这样使用它: options = extend(true, defaults, options); 您的设置对象可能类似于以下内容,并将正确地合并在默认值之上: var settings = { text: "Other text", dataObj:{ links: 3531 } }; Similar question asked here ...
-
对于第一次编辑,我建议您将对象更改为其他形式 var object = { "10-10-2017": "Black friday", "11-09-2017": "Some holiday", "10-10-2017": "Fathers day" } 至 var object =[ {"date":"10-10-2017","value":"Black friday"}, {"date":"11-09-2017","value":"Some holiday"}, {"date":"10-10-2017 ...
-
合并Javascript对象,似乎无法找到正确的方法[重复](Merge Javascript objects, can't seem to find correct way [duplicate])[2023-05-17]
你可以这样做: var mergedObj={}; for(var key in personformdata[i]) mergedObj[key]=personformdata[i][key]; for(var key in address_ids[i]) mergedObj[key]=address_ids[i][key]; 或者如果你使用jQuery: var mergedObj={}; $.extend(mergedObj, personformdata[i], address_i ... -
合并JavaScript对象(Merge JavaScript objects)[2023-05-30]
这应该工作。 var array = [] array.push(yourObject); 这会将你的对象放到一个数组中,如果你把一个相同的对象集合成一个,那么应该使用它。 将不同的值合并到一个对象中: function makeObject(){ var obj = {}; obj['info'] = somevalue; //arguments [0] maybe obj['power'] = somevalue; obj['accuracy'] = s ... -
对象数组(JavaScript)合并并添加具有相同键的属性(Array of Objects (JavaScript) merge and add properties with same key)[2022-05-02]
您只需循环遍历数组并将值推送到新数组中,首先检查item_name是否已存在。 检查对象是否已在新数组中的更简单方法是使用item_name及其在新数组中的位置创建对象。 否则,每次检查都需要循环遍历新数组。 试试这个: function merge_data(array){ var new_array = [], item_map = {}; // Loop over the array array.forEach(function(v){ var ...