Java-17.4同期の詳細を最初から認識(3)-オブジェクトロック
3789 ワード
この章では、前の章の問題に続いて、オブジェクトロックという解決策を示します.
1.オブジェクトロックとは?
オブジェクトロックとは、Javaが臨界領域synchronized(Object)文で指定したオブジェクトに対してロックをかけることであり、オブジェクトロックは排他的排他ロックである.
2.臨界区とは何ですか.
臨界領域とは、プログラム内のコードセグメントを指し、このコードでは、同じオブジェクトに単独で同時スレッドでアクセスします.Javaでは、キーワード「synchronized」で臨界領域を識別します.
3.一般的なオブジェクトロック:synchronizedとReentrantLock
次に、2つのコード例を示します(次の2つの例は、以前の銀行のコードに基づいて修正され、主にBankのコードを修正し、他のものは変更されません).
コード投稿接続:http://blog.csdn.net/raylee2007/article/details/50496784
修正されたコード:
synchronizedの使用
ReentrantLockの使用:
テストコードで出力:
16口座から転出 6853.31元、80口座から振り込む 6853.31元、総数:100000.00元5口座から転出 819.37元、92口座から振り込む 819.37元、総数:100000.00元12口座から転出 1278.62元、67口座から振り込む 1278.62元、総数:100000.00元3口座から転出 1353.74元、9口座から振り込む 1353.74元、総数:100000.00元94口座から転出 2316.07元、83口座から振り込む 2316.07元、総数:100000.00元59口座から転出 2563.51元、90口座から振り込む 2563.51元、総数:100000.00元82口座から転出 6276.89元、30口座から振り込む 6276.89元、総数:100000.00元2口座から転出 6175.01元、80口座から振り込む 6175.01元、総数:100000.00元21口座から転出 50300.61元、80口座から振り込む 50300.61元、総数:100000.00元
……(など)
出力により,総数はもはや変動せず,誤差は生じないことがわかる.
まとめ:この章では、主に同期の方法:オブジェクトロック、および一般的な2つのオブジェクトロックについて説明します.
この章はここまでです.ありがとうございます.
-----------------------------------
目次
1.オブジェクトロックとは?
オブジェクトロックとは、Javaが臨界領域synchronized(Object)文で指定したオブジェクトに対してロックをかけることであり、オブジェクトロックは排他的排他ロックである.
2.臨界区とは何ですか.
臨界領域とは、プログラム内のコードセグメントを指し、このコードでは、同じオブジェクトに単独で同時スレッドでアクセスします.Javaでは、キーワード「synchronized」で臨界領域を識別します.
3.一般的なオブジェクトロック:synchronizedとReentrantLock
次に、2つのコード例を示します(次の2つの例は、以前の銀行のコードに基づいて修正され、主にBankのコードを修正し、他のものは変更されません).
コード投稿接続:http://blog.csdn.net/raylee2007/article/details/50496784
修正されたコード:
synchronizedの使用
package com.ray.ch17;
public class Bank {
private final double[] accounts;
public double[] getAccounts() {
return accounts;
}
public Bank(int n, double initBalance) {
accounts = new double[n];
for (int i = 0; i < accounts.length; i++) {
accounts[i] = initBalance;
}
}
public double getTotal() {
double total = 0;
for (int i = 0; i < accounts.length; i++) {
total += accounts[i];
}
return total;
}
public synchronized void transfer(int fromAccount, int toAccount,
double money) {
if (accounts[fromAccount] < money) {
return;
}
accounts[fromAccount] -= money;
System.out.printf(" " + fromAccount + " %10.2f ,", money);
accounts[toAccount] += money;
System.out.printf(" " + toAccount + " %10.2f ,", money);
System.out.printf(" :%10.2f ", getTotal());
System.out.println();
}
public int size() {
return accounts.length;
}
}
ReentrantLockの使用:
package com.ray.ch17;
import java.util.concurrent.locks.ReentrantLock;
public class Bank {
private final double[] accounts;
private ReentrantLock reentrantLock = new ReentrantLock();
public double[] getAccounts() {
return accounts;
}
public Bank(int n, double initBalance) {
accounts = new double[n];
for (int i = 0; i < accounts.length; i++) {
accounts[i] = initBalance;
}
}
public double getTotal() {
double total = 0;
for (int i = 0; i < accounts.length; i++) {
total += accounts[i];
}
return total;
}
public void transfer(int fromAccount, int toAccount, double money) {
reentrantLock.lock();
try {
if (accounts[fromAccount] < money) {
return;
}
accounts[fromAccount] -= money;
System.out.printf(" " + fromAccount + " %10.2f ,", money);
accounts[toAccount] += money;
System.out.printf(" " + toAccount + " %10.2f ,", money);
System.out.printf(" :%10.2f ", getTotal());
System.out.println();
} finally {
reentrantLock.unlock();
}
}
public int size() {
return accounts.length;
}
}
テストコードで出力:
16口座から転出 6853.31元、80口座から振り込む 6853.31元、総数:100000.00元5口座から転出 819.37元、92口座から振り込む 819.37元、総数:100000.00元12口座から転出 1278.62元、67口座から振り込む 1278.62元、総数:100000.00元3口座から転出 1353.74元、9口座から振り込む 1353.74元、総数:100000.00元94口座から転出 2316.07元、83口座から振り込む 2316.07元、総数:100000.00元59口座から転出 2563.51元、90口座から振り込む 2563.51元、総数:100000.00元82口座から転出 6276.89元、30口座から振り込む 6276.89元、総数:100000.00元2口座から転出 6175.01元、80口座から振り込む 6175.01元、総数:100000.00元21口座から転出 50300.61元、80口座から振り込む 50300.61元、総数:100000.00元
……(など)
出力により,総数はもはや変動せず,誤差は生じないことがわかる.
まとめ:この章では、主に同期の方法:オブジェクトロック、および一般的な2つのオブジェクトロックについて説明します.
この章はここまでです.ありがとうございます.
-----------------------------------
目次