在线程之间创建延迟(Creating delay between threads)
所有,我有一个api调用,由许多线程调用。 唯一的问题是延迟下注。 线程应该至少1秒。 我意识到 - 没有同步块 - 如果一个线程在时间t1调用api,那么所有其他线程等待1秒,然后所有其他线程在t1 + 1秒调用api。 这不是我想要的,所以我将整个等待块放在synchronized块中,只要一个线程正在等待所有其他线程阻塞。
这有效; 但是,我认为这不是最有效的方法。
非常感谢任何建议。
private static volatile AtomicLong lastAPICall = new AtomicLong(); private void callAPI() { // 1 sec plus a little extra final long oneMS = 1 * 1000 + 100; long lastCall = 0; long timeDiff = 0; synchronized (lastAPICall) { timeDiff = System.currentTimeMillis() - lastAPICall.get(); lastCall = lastAPICall.getAndSet(System.currentTimeMillis()); } } if (System.currentTimeMillis() - lastCall < oneMS) { synchronized (lastAPICall) { try { long sleep = oneMS - timeDiff; Thread.sleep(oneMS - timeDiff); } catch (InterruptedException ignore) {} finally { lastAPICall.set(System.currentTimeMillis()); log.info("Thread: " + Thread.currentThread().getId() + " calling the api at this time: " + System.currentTimeMillis()); } } } try { // API CALL } catch (IOException t){ throw t; } finally { synchronized (lastAPICall) { lastAPICall.set(System.currentTimeMillis()); } } // Log files for running the code with 4 threads Thread: 35 calling the api at this time: 1456182353694 Thread: 34 calling the api at this time: 1456182354795 Thread: 37 calling the api at this time: 1456182355905 Thread: 36 calling the api at this time: 1456182357003
All, I have an api call which is called by many threads. The only issue is that the delay bet. threads should be at least 1 second. I realized - w/o the synchronized block - if one thread is calling the api at time t1, then all other threads wait for 1 second and then all other threads call the api at t1 + 1 second. This is not I want, so I put the whole wait block in synchronized block that as long as one thread is waiting all other threads block.
This works; however, I think its not the most efficient way to do this.
Any recommendations is greatly appreciated.
private static volatile AtomicLong lastAPICall = new AtomicLong(); private void callAPI() { // 1 sec plus a little extra final long oneMS = 1 * 1000 + 100; long lastCall = 0; long timeDiff = 0; synchronized (lastAPICall) { timeDiff = System.currentTimeMillis() - lastAPICall.get(); lastCall = lastAPICall.getAndSet(System.currentTimeMillis()); } } if (System.currentTimeMillis() - lastCall < oneMS) { synchronized (lastAPICall) { try { long sleep = oneMS - timeDiff; Thread.sleep(oneMS - timeDiff); } catch (InterruptedException ignore) {} finally { lastAPICall.set(System.currentTimeMillis()); log.info("Thread: " + Thread.currentThread().getId() + " calling the api at this time: " + System.currentTimeMillis()); } } } try { // API CALL } catch (IOException t){ throw t; } finally { synchronized (lastAPICall) { lastAPICall.set(System.currentTimeMillis()); } } // Log files for running the code with 4 threads Thread: 35 calling the api at this time: 1456182353694 Thread: 34 calling the api at this time: 1456182354795 Thread: 37 calling the api at this time: 1456182355905 Thread: 36 calling the api at this time: 1456182357003
原文:https://stackoverflow.com/questions/35566320
最满意答案
OP在这里。 经过一番广泛的搜索和实验,我得出结论,这不能在SQL中完成。 我写了一个简短的脚本来为我做这项工作,类似于问题中列出的伪代码。 通过事务实现ACID合规性(如果这很重要,请检查您的DBMS以获取详细信息)。
OP here. After some extensive searching and experimentation, I have come to the conclusion this cannot be done in SQL. I wrote a short script to do this work for me, similar to the pseudocode listed in the question. ACID compliance is achieved by transactions (check your DBMS for details if this is important).
相关问答
更多-
UPDATE tobeupdated INNER JOIN original ON (tobeupdated.value = original.value) SET tobeupdated.id = original.id 那应该做到这一点,真正地做你自己的事情。 但是,我喜欢'JOIN'语法用于连接,而不是多个'WHERE'条件。 我觉得它更容易阅读 如果它的运行速度很慢桌子有多大? 您应该有tobeupdated.value和original.value的索引 编辑:我们也可以简化查询 UPDATE ...
-
您不希望在UPDATE语句中使用fylker 。 您还应该使用正确的join 。 所以第一次重写是: UPDATE companies c JOIN kommuner k ON c.forretningsadresse_kommune = k.kommuneNavn SET c.forretningsadresse_fylke = (SELECT f.fylkeNavn FROM fylker ...
-
您需要有一个join语句来组合来自多个表的数据。 以下可能是您正在寻找的。 UPDATE detail INNER JOIN `result` ON `result`.Admno = detail.Admno AND `result`.Code = detail.ModuleCode SET detail.PASS=`result`.PASS You'll need to have a join statement to combine data from multiple tables. Below i ...
-
解决问题时最重要的是用简单的英语来理解这种方法。 例如,在这里,您只需要找到两个最接近的非NULL值,即前一个和后一个最近的值。 当它们存在且相等时,使用它们的价值。 以下是将此方法转换为SQL: select t.*, isnull(t.Val, case when pr.Val = nr.Val then pr.Val end) as [NewVal] from @table t outer apply ( select top (1) tp.Val from @table tp ...
-
可能是这样的: - SELECT a.product_id, a.name, b.zone_id FROM products a INNER JOIN product_to_zone b ON a.product_id = b.product_id UNION SELECT a.product_id, a.name, 10 FROM products a LEFT OUTER JOIN product_to_zone b ON a.product_id = b.product_id WHERE b.prod ...
-
我会使用显式join编写此查询: UPDATE table1 join table2 ON table1.col1 = table2.col1 AND table1.col2 = table2.col2 SET table1.col3 = table2.col3; 但不管怎样,你需要一个索引。 我推荐table2(col1, col2, col3) : create index idx_table2_col1_col2_col3 on table2(col1, col2 ...
-
mysql表没有得到更新(mysql table is not getting updated)[2022-03-20]
看看这个问题 ,提问者和你有同样的问题; 通过删除.AcceptChanges();解决它.AcceptChanges(); 命令。 实际上,您已经告诉缓冲区已经写回了更改,因此当您再创建更多时,它们不会被提交。 Take a look over at this SO question the asker had the same problem as you; it was resolved by removing the .AcceptChanges(); command. In effect you ... -
OP在这里。 经过一番广泛的搜索和实验,我得出结论,这不能在SQL中完成。 我写了一个简短的脚本来为我做这项工作,类似于问题中列出的伪代码。 通过事务实现ACID合规性(如果这很重要,请检查您的DBMS以获取详细信息)。 OP here. After some extensive searching and experimentation, I have come to the conclusion this cannot be done in SQL. I wrote a short script to ...
-
我假设您已经拥有project表中的所有条目但是它们缺少Field_X属性? 所以你需要的是更新,而不是插入 UPDATE project p, client c, project_client pc SET p.Field_X=c.Field_X WHERE p.ID=pc.ProjectID AND c.ID=pc.ClientID 但是,请注意,在两个地方拥有相同的数据并不是一个好习惯; 如果可能的话,总是只在一个地方放一个事实。 I assume you already have all entr ...
-
如何使用MySQL从另一个表更新一个表时处理NULL(How to handle NULLs when updating one table from another using MySQL)[2022-04-22]
我没有测试过这个,但认为这样的东西会起作用: UPDATE table_1 SET data_2 = NULL WHERE data_1 IN(SELECT table_1.data_1 FROM table_1, table_2 WHERE table_1.data_1 = table_2.data_1) 当我需要关于如何处理某些事情的不同想法时,我喜欢这个资源: http : //www.artfulsoftware.com/infotree/queries.php 更新: UPDA ...