首页 / 操作系统 / Linux / Java并发编程实战(使用synchronized实现同步方法)
本文介绍Java最基本的同步方式,即使用synchronized关键字来控制一个方法的并发访问,如果一个对象已用synchronized关键字声明,那么只有一个执行线程允许去访问它,其它试图访问这个对象的线程将被挂起,直到第一个线程访问完毕。还有一篇:Java并发编程:synchronized http://www.linuxidc.com/Linux/2015-07/120169.htm 下面通过一个小例子来学习这个概念,公司向银行存钱,取钱场景。 1:创建Account的账号类,它是银行账户的模型,只有一个双精度浮点型属性,balance. 2:实现balance的get set 方法。 3:实现AddAmount()方法,将传入的数量加到余额balance中,并且在同一时间只允许一个线程去改变这个值,使用synchronized关键字。 4:实现SubtractAmount()方法,将传入的数量从余额balance中扣除,并且在同一时间只允许一个线程去改变这个值。 具体代码:public class Account { /** * Balance of the bank account */ private double balance; /** * Returns the balance of the account * @return the balance of the account */ public double getBalance() { return balance; } /** * Establish the balance of the account * @param balance the new balance of the account */ public void setBalance(double balance) { this.balance = balance; }
/** * Add an import to the balance of the account * @param amount import to add to the balance */ public synchronized void addAmount(double amount) { double tmp=balance; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } tmp+=amount; }
/** * Subtract an import to the balance of the account * @param amount import to subtract to the balance */ public synchronized void subtractAmount(double amount) { double tmp=balance; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } tmp-=amount; balance=tmp; }
}5:实现一个ATM模拟类Bank,它使用subtractAmount()方法对账户的余额进行扣除,实现Runabl接口。具体代码:public class Bank implements Runnable { /** * The account affected by the operations */ private Account account;
/** * Constructor of the class. Initializes the account * @param account The account affected by the operations */ public Bank(Account account) { this.account=account; }
/** * Core method of the Runnable */ public void run() { for (int i=0; i<100; i++){ account.subtractAmount(1000); } }}6:实现公司模拟类,调用addAmount()方法进行存钱,实现Runabl接口。 具体代码:public class Company implements Runnable { /** * The account affected by the operations */ private Account account;
/** * Constructor of the class. Initializes the account * @param account the account affected by the operations */ public Company(Account account) { this.account=account; }
/** * Core method of the Runnable */ public void run() { for (int i=0; i<100; i++){ account.addAmount(1000); } }7:在主方法中调用测试:通过线程的join方法,在存期那,取钱线程模拟完毕后打印出结构。public class Main { /** * Main method of the example * @param args */ public static void main(String[] args) { // Creates a new account ... Account account=new Account(); // an initialize its balance to 1000 account.setBalance(1000);
// Creates a new Company and a Thread to run its task Company company=new Company(account); Thread companyThread=new Thread(company); // Creates a new Bank and a Thread to run its task Bank bank=new Bank(account); Thread bankThread=new Thread(bank);
// Prints the initial balance System.out.printf("Account : Initial Balance: %f
",account.getBalance());
// Starts the Threads companyThread.start(); bankThread.start(); try { // Wait for the finalization of the Threads companyThread.join(); bankThread.join(); // Print the final balance System.out.printf("Account : Final Balance: %f
",account.getBalance()); } catch (InterruptedException e) { e.printStackTrace(); } } }结果,相同时间内,存与取执行后应该是相等的。如果我们在方法中不去使用synchronized关键字,那么得出的结果就不对了。
Account : Initial Balance: 1000.000000 Account : Final Balance: 1000.000000本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-07/120168.htm