这一章节我们接着上一章节的问题,给出一个解决方式:对象锁。
1.什么是对象锁?
对象锁是指Java为临界区synchronized(Object)语句指定的对象进行加锁,对象锁是独占排他锁。
2.什么是临界区?
临界区是指程序中的一个代码段,在这段代码中,单独并发的线程对同一个对象进行訪问。在Java中。用keyword“synchronized”标识一个临界区。
3.经常使用的对象锁:synchronized和ReentrantLock
我们以下给出两个代码样例(以下两个样例都是依据之前的银行的代码来改动的。主要改动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元,总数:1000000.00元
从5账户转出 819.37元,从92账户转入 819.37元,总数:1000000.00元
从12账户转出 1278.62元,从67账户转入 1278.62元,总数:1000000.00元
从3账户转出 1353.74元,从9账户转入 1353.74元,总数:1000000.00元
从94账户转出 2316.07元,从83账户转入 2316.07元,总数:1000000.00元
从59账户转出 2563.51元,从90账户转入 2563.51元,总数:1000000.00元
从82账户转出 6276.89元,从30账户转入 6276.89元,总数:1000000.00元
从2账户转出 6175.01元,从80账户转入 6175.01元,总数:1000000.00元
从21账户转出 5030.61元,从80账户转入 5030.61元,总数:1000000.00元
……(等等)
通过输出能够看见。总数已经是不再变动,不再出现误差。
总结:这一章节主要讨论了同步的方法:对象锁,以及经常使用的两个对象锁。
这一章节就到这里。谢谢。
———————————–