Неизменность и синхронизация на JavaJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Неизменность и синхронизация на Java

Сообщение Anonymous »

С тех пор, как я прочитал параллелизм Java на практике, мне было интересно, как я мог бы использовать неизменность , чтобы упростить проблемы синхронизации между потоками. Его состояние не может измениться после инициализации, поэтому вообще не может быть «общих изменяющихся состояний». Но неизменные объекты должны быть правильно использованы, чтобы считаться полезным в задачах синхронизации.

Код: Выделить всё

public class Bank {

public static final int NUMBER_OF_ACCOUNT = 100;

private double[] accounts = new double[NUMBER_OF_ACCOUNT];

private Lock lock;
private Condition sufficientFunds;

public Bank(double total) {
double singleAmount = total / 100D;
for (int i = 0; i < NUMBER_OF_ACCOUNT; i++) {
accounts[i] = singleAmount;
}
lock = new ReentrantLock();
sufficientFunds = lock.newCondition();
}

private double getAdditionalAmount(double amount) throws InterruptedException {
Thread.sleep(1000);
return amount * 0.04D;
}

public void transfer(int from, int to, double amount) {
try {
// Not synchronized operation
double additionalAmount = getAdditionalAmount(amount);
// Acquiring lock
lock.lock();
// Verifying condition
while (amount + additionalAmount > accounts[from]) {
sufficientFunds.await();
}
// Transferring funds
accounts[from] -= amount + additionalAmount;
accounts[to] += amount + additionalAmount;
// Signaling that something has changed
sufficientFunds.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public double getTotal() {
double total = 0.0D;
lock.lock();
try {
for (int i = 0; i < NUMBER_OF_ACCOUNT; i++) {
total += accounts[i];
}
} finally {
lock.unlock();
}
return total;
}

public static void main(String[] args) {
Bank bank = new Bank(100000D);

for (int i = 0; i < 1000; i++) {
new Thread(new TransferRunnable(bank)).start();
}
}
}
< /code>
В приведенном выше примере, который поступает из основной книги Java Volume I, используется синхронизация через явные блокировки. Код явно сложно читать и подвергать ошибке. Я попытался создать об неизменные учетные записи 
класс для сохранения значения счетов, предоставляя банку Class a volatile экземпляр учетных записей . Однако я не достиг своей цели. Я знаю, что неизменная объект не может изменить свое состояние после его создания. И я знаю, что для правил, реализованных в модели памяти Java (JSR-133), неизменные объекты гарантированно рассматриваются полностью построены после их инициализации (с некоторыми различными ).
Затем я попытаюсь использовать эти концепции, чтобы удалить синхронизацию ясной синхронизации из банка . Я разработал эти неизменные учетные записи класс:

Код: Выделить всё

class Accounts {
private final List accounts;

public Accounts(List accounts) {
this.accounts = new CopyOnWriteArrayList(accounts);
}

public Accounts(Accounts accounts, int from, int to, double amount) {
this(accounts.getList());
this.accounts.set(from, -amount);
this.accounts.set(to, amount);
}

public double get(int account) {
return this.accounts.get(account);
}

private List getList() {
return this.accounts;
}
}
Атрибут учетных записей класса Bank должен быть опубликован с использованием volatile переменной:

Код: Выделить всё

private volatile Accounts accounts;
Очевидно, что метод передачи класса Bank будет изменен соответственно:

Код: Выделить всё

public void transfer(int from, int to, double amount) {
this.accounts = new Accounts(this.accounts, from, to, amount);
}
< /code>
Используя неизменное объект (Accounts
) для хранения состояния класса () должен быть шаблоном публикации, который описан в пункте 3.4.2 книги JCIP.>

Подробнее здесь: https://stackoverflow.com/questions/340 ... on-in-java
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»