Да, вы можете синхронизировать, используя массив в качестве объекта монитора, потому что массивы (даже массивы примитивов) являются объектами в Java.
Вы можете синхронизировать блок кода на определенном мониторе, например:
public void myMethod() {
unsynchronized_statements...
synchronized(myMonitorObject) {
synchronized_statments...
}
Рекомендуется синхронизировать как можно меньше строк кода.
Синхронизация кода на мониторе никак не влияет на монитор, а влияет только на потоки, обращающиеся к синхронизированному блоку.кода.Прежде чем выполнение потока сможет войти в блок кода, он должен получить «блокировку» на мониторе.Среда выполнения Java гарантирует, что не более одного потока одновременно может иметь «блокировку» на мониторе. Таким образом, синхронизация в вашем массиве не запрещает несинхронизированные блоки кода для доступа к нему! Хитрость заключается в том, чтобы убедиться, что все операции, которые вы не хотите выполнять одновременно, находятся внутри блоков, синхронизированных на одном и том жеmonitor.
Поскольку Java не предлагает многомерные массивы, а только массивы массивов, вы, безусловно, можете синхронизировать вложенный массив для более детальной синхронизации.Если вы моделируете 2d-массив как массив строк, вы можете синхронизировать только по строкам, а не по столбцам, поскольку в этом примере столбцы не представлены в виде отдельных массивов.
Вы можете синхронизировать только значения одного массива, если они не являются простыми, поэтому Integer () вместо int.Обратите внимание, что Integer () является неизменным объектом, поэтому вы не сможете изменить его значение.Решением было бы создать свой собственный объект-обертку Cell () с помощью метода get и set для содержащегося числового значения.Это позволит вам позволить потоку получить блокировку ячейки и безопасно изменить ее значение.
Поскольку у меня выходной, я решил повеселиться и создал рабочий пример того, что вы описываете.Да, это моя идея повеселиться.
Классы:
Приложение запускает несколько операций над одной матрицей.Единственный синхронизированный блок кода находится в классе Operation.Если вы удалите синхронизацию, результаты будут неправильными, потому что две операции одновременно манипулируют одной и той же строкой.
Вывод при синхронизации:
[105, 104, 103, 102, 101]
[110, 109, 108, 107, 106]
[115, 114, 113, 112, 111]
[120, 119, 118, 117, 116]
[125, 124, 123, 122, 121]
[130, 129, 128, 127, 126]
[135, 134, 133, 132, 131]
[140, 139, 138, 137, 136]
[145, 144, 143, 142, 141]
[150, 149, 148, 147, 146]
Пример вывода при НЕ синхронизированной:
[105, 4, 103, 102, 101]
[110, 9, 108, 207, 106]
[115, 14, 113, 212, 111]
[120, 19, 118, 217, 116]
[125, 124, 123, 122, 121]
[130, 129, 128, 127, 126]
[135, 34, 133, 232, 131]
[140, 139, 138, 137, 136]
[145, 144, 143, 142, 141]
[150, 149, 148, 147, 146]
Обратите внимание, что я добавил несколько операторов Thread.sleep () в реализации операций, чтобы сделать разницу между синхронизированным и несинхронизированным выполнением более очевидной.