/ / Вибіркове забезпечення синхронізації для сприяння максимальній паралельності - java, багатопотоковість, паралельність, синхронізація, очікування

Вибіркове застосування синхронізації для полегшення максимальної сумісності - java, багатопоточність, паралельність, синхронізація, очікування

Ось, що я намагаюся зробити з Java:

while(writeSetsIntersect()) {
wait();
}
doStuff
notifyAll();

Ось де я застряг: doStuff може виконуватися одночасно, якщо два потоки записують у різні змінні, тобто вони мають неперервні набори записів. Якщо набори запису перетинаються, потоки повинні чергуватися. Тому я не можу просто сказати doStuff в синхронізованому блоці, оскільки це не завжди (і може ніколи не бути) необхідним.

Я міг зафіксувати елементи в наборі запису, але якщо два потоки з перетинаючимися наборами записів чекають на одному і тому ж блокуванні, може статися тупик. Як от:

Lock[] locks = new Lock[allAvailableVariables.length];
public void getLocks() {
for(i = 0; i < allAvailableVariables.length; i++)
if(i is in writeSet)
locks[i].lock();
}

Найпростіший спосіб уникнути цього (наскільки я можупридумати) - це синхронізувати придбання замків у вашому наборі записів. Але, якщо два потоки з набором записів, що перетинаються, змагаються, щоб потрапити в блок синхронізації, потоку з набором запису, що не перетинається з двома іншими, доведеться зачекати, поки вони не покинуть блок синхронізації.

Я думаю, я міг би просто мати фіксацію віджиму, але я хотів би уникнути цього, якщо це можливо, оскільки оцінка того, чи перетинаються набори запису, може бути дорогою.

Це взагалі має сенс?

Відповіді:

3 для відповіді № 1

Схоже, ви хочете скористатися замовленням замків.

Відсортуйте замки в якомусь природному порядку. Потім зафіксуйте кожен по черзі.

Припустимо, у вас є замки a і b з a < b. Якщо два потоки хочуть зафіксувати обидва a і b, вони обидва заблокуються a спочатку. Тож у вас не може виникнути ситуація, коли нитка заблокувалась b і заблоковано a, в той час як інший потік заблоковано a заблоковано b.