java - 想要将进程转换为多线程进程

标签 java multithreading concurrency

让我回顾一下我的代码正在做什么(尚未编码),我想让它在多个线程中运行以加快速度。

  1. 在数据库中查找尚未处理的记录:

    SELECT TOP 1 * FROM Products WHERE isActive = 1
    
  2. 查找 URL(Rest 调用),返回 HTML 并将其存储在数据库中

  3. 设置该行的标志:

    UPDATE Products SET isActive = 0 WHERE rowId = 234
    

假设我将以上内容包装到一个方法中:

public void UpdateProduct()
{
}

是否可以让这个进程在多个线程中运行? (比如 2 或 3)?

更新 有人可以向我展示如何将此方法包装到多线程进程中的骨架结构吗?

最佳答案

由于最慢的 Activity 是 html 检索,因此可以使用 20、50 甚至 200 个检索线程线性加速,具体取决于 ISP 带宽相对于服务器返回数据的速度。

将表半虚拟化为内存数组可能是明智的。因此,每个寻找工作的线程都会查询一个类成员函数,该函数返回下一个可用行或处理完成后的更新。如果有其他更新程序,该类还应该偶尔检测数据库更新,并每隔几秒或几分钟将内存中的更新刷新回 d/b。

我不懂 Java,所以这里是 PHPish 术语中的印象派算法:

class virtualProduct {

  const time_t maxSync = 10;  // maximum age for unsynched d/b to row[]

  static struct {  // singleton
     int isActive;
     int urlRowId;
     etc ...
  } row [];

  static time_t lastSync;  // timestamp of last sync with d/b

  static mutex theLock;  // mutex to protect read/write of above


  function syncData()
  {
     lock (&theLock);

     // flush local updates to d/b
     foreach (row as item)
         if (item.updated)
         {
               sql_exec ("update products set whatever = " + value + " where rowId = " + whatever);
               if (okay)
                    item .updated = false;
         }

     // update from d/b (needed if other entities are updating it)
     sql_query ("select * from products");

     row [] = sql results;
     lastSync = now();
     unlock (&theLock);
  }

  function virtualProduct ()  // constructor
  {
      ...
      syncData();  // initialize memory copy of d/b
  }

  function ~virtualProduct ()  // destructor
  {
      syncData();  // write last updates
      ...
  }

  function UpdateItem(int id)
  {
     lock (&theLock);
     if (now () - lastSync > maxSync)
         syncData();
     int index = row.find (id);
     if (index >= 0)
     {
         row [index] .fields = whatever;
         row [index] .isActive = 0;
     }
     unlock (&theLock);
  }

  function ObtainNextItem()
  {
     lock (&theLock);
     if (now () - lastSync > maxSync)
         syncData();
     result = null;
     foreach (row as item)
         if (item.isActive == 1)
         {
              item.isActive = 2;  // using Peter Schuetze's suggestion
              result = item.id;
              break;
         }
     unlock (&theLock);
     return result;
  }
}

仍有一些小问题需要修复,例如 UpdateItemObtainNextItem 中互斥锁的双重锁定(通过调用 syncData),但当转化为实际实现时,这个问题很容易解决。

关于java - 想要将进程转换为多线程进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2007792/

相关文章:

java - Win32 文件属性对话框未通过 JNI 在 Java Swing 应用程序中显示

java - 有人可以向我解释线程吗?

c++ - 编写数据结构以对每个线程使用不同的缓存行以避免线程抖动?

java - 卡在受信号量保护的交互中

java - Double 无法转换为 JTextField

java - 如何在oracle上使用wso2连接池避免非 Activity session ?

java - 请解释一下 Long 相等条件

python - 在 python 中运行几分钟的计时器

c++ - std::atomic 的正确用法

javascript - 了解异步模块中的并发/并行性 - Node JS