Лучшее решение действительно зависит от типов операций, которые вы выполняете в электронной таблице. Например, если одному потоку нужно прочитать значение, записанное другим потоком, то, вероятно, необходимо заблокировать либо всю электронную таблицу, либо хотя бы отдельные строки за раз. Поскольку сама таблица не является поточно-ориентированной, вы правы в том, что вам нужно выполнить собственную синхронизацию.
Если важно сериализовать весь доступ (что снижает производительность, так как избавляется от параллелизма), рассмотрите возможность использования потоково-безопасной очереди, где каждый поток добавляет объект в очередь, представляющий операцию, которую он хочет выполнить. Затем вы можете заставить рабочий поток извлекать элементы из очереди (опять же, потокобезопасным способом, поскольку очередь является поточно-ориентированной) и выполнять операцию.
Здесь может быть место для распараллеливания работников очереди, поскольку они могут связываться друг с другом и делать между собой некоторую блокировку на основе строк. Например, если первой операцией является чтение строк 1-4 и запись в строку 5, а второй операцией является чтение строк 6-10 и запись в строку 11, то они должны выполняться параллельно. Но будьте осторожны, так как это может зависеть от базовой структуры таблицы, которая, как вы говорите, не является поточно-ориентированной. Тем не менее, чтение, вероятно, хорошо для параллельного выполнения.
Хотя нетривиальная синхронизация доступа к очереди является основной проблемой читателей-писателей, и хотя вам нужно избегать как голода, так и тупиков, гораздо проще думать о ней, чем произвольный доступ к электронной таблице. .
Тем не менее, лучшим решением будет использование многопоточной электронной таблицы или использование только одного потока для доступа к ней. Почему бы не использовать электронную таблицу на основе базы данных, а затем иметь несколько потоков для чтения / записи базы данных одновременно?