zoukankan      html  css  js  c++  java
  • 从头认识java-17.4 具体解释同步(3)-对象锁

    这一章节我们接着上一章节的问题,给出一个解决方式:对象锁。

    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元

    ......(等等)


    通过输出能够看见。总数已经是不再变动,不再出现误差。


    总结:这一章节主要讨论了同步的方法:对象锁,以及经常使用的两个对象锁。




    这一章节就到这里。谢谢。

    -----------------------------------

    文件夹

  • 相关阅读:
    Android第三次作业
    Android第二次作业
    2016-2017-2软件工程课程总结
    软件工程——个人总结
    软件工程——团队答辩
    软件工程——团队作业4
    软件工程——团队作业3
    软件工程——团队作业2
    软件工程——团队作业1
    软件工程第二次作业——结对编程
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7102301.html
Copyright © 2011-2022 走看看