У меня есть набор вопросов, касающихся многопоточности Java. Пожалуйста, предоставьте мне столько же помощи, сколько сможете.
0) Предположим, у нас есть 2 банковских счета, и нам нужно переводить деньги между ними поточно-безопасным способом. т.е.
accountA.money += transferSum;
accountB.money -= transferSum;
Существуют два требования:
- никто не должен видеть промежуточные результаты операции (т.е. одна учетная сумма увеличивается, но другие еще не уменьшены)
- доступ к чтению не должен блокироваться во время операции (т.е. старые значения сумм счета должны отображаться во время работы)
Можете ли вы предложить некоторые идеи по этому поводу?
1) Предположим, что 2 потока изменяют некоторое поле класса с помощью синхронизированного метода или используют явный блокировку. Независимо от синхронизации, нет никакой гарантии, что это поле будет видимым для потоков, которые читают его через НЕ синхронизированный метод. - Правильно ли это?
2) Как долго поток, пробужденный методом уведомления, может ждать блокировки? Предположим, у нас есть такой код:
synchronized(lock) {
lock.notifyall();
//do some very-very long activity
lock.wait() //or the end of synchronized block
}
Можно ли утверждать, что хотя бы один поток будет успешным и захватит блокировку? Может ли сигнал потеряться из-за некоторого времени ожидания?
3) Цитата из Java Concurrency Книга:
"Однопоточные исполнители также обеспечивают достаточную внутреннюю синхронизацию, гарантирующую, что любые записи в памяти, сделанные задачами, видны для последующих задач, это означает, что объекты могут быть безопасно ограничены" потоком задачи ", хотя этот поток можно заменить на другой время от времени".
Означает ли это, что единственной проблемой безопасности потока, которая остается для кода, выполняемого в однопоточном исполнителе, является гонка данных, и мы можем отказаться от изменчивых переменных и игнорировать все проблемы видимости? Это похоже на универсальный способ решить большую часть проблем Concurrency.
4) Все стандартные геттеры и сеттеры являются атомарными. Они не должны синхронизироваться, если поле отмечено как изменчивое. - Правильно ли это?
5) Инициирование статических полей и статических блоков выполняется одним потоком и, следовательно, не нужно синхронизировать. - Правильно ли это?
6) Почему поток должен уведомлять других, если он покидает метод lock с помощью метода wait(), но не нужно делать это, если он покидает блокировку, выходя из синхронизированного блока?