频道栏目
首页 > 资讯 > Java > 正文

Java并发编程实战(使用synchronized实现同步方法)

15-07-20        来源:[db:作者]  
收藏   我要投稿
   本文介绍java最基本的同步方式,即使用synchronized关键字来控制一个方法的并发访问,如果一个对象已用synchronized关键字声明,那么只有一个执行线程允许去访问它,其它试图访问这个对象的线程将被挂起,直到第一个线程访问完毕。
 
   下面通过一个小例子来学习这个概念,公司向银行存钱,取钱场景。
 
  1:创建Account的账号类,它是银行账户的模型,只有一个双精度浮点型属性,balance.
 
  2:实现balance的get set 方法。
 
  3:实现AddAmount()方法,将传入的数量加到余额balance中,并且在同一时间只允许一个线程去改变这个值,使用synchronized关键字。
 
  4:实现SubtractAmount()方法,将传入的数量从余额balance中扣除,并且在同一时间只允许一个线程去改变这个值。
 
  具体代码:
 
    
 
 1 public class Account {
 2 
 3     /**
 4      * Balance of the bank account
 5      */
 6     private double balance;
 7 
 8     /**
 9      * Returns the balance of the account
10      * @return the balance of the account
11      */
12     public double getBalance() {
13         return balance;
14     }
15 
16     /**
17      * Establish the balance of the account
18      * @param balance the new balance of the account
19      */
20     public void setBalance(double balance) {
21         this.balance = balance;
22     }
23     
24     /**
25      * Add an import to the balance of the account
26      * @param amount import to add to the balance
27      */
28     public synchronized void addAmount(double amount) {
29             double tmp=balance;
30             try {
31                 Thread.sleep(10);
32             } catch (InterruptedException e) {
33                 e.printStackTrace();
34             }
35             tmp+=amount;
36     }
37     
38     /**
39      * Subtract an import to the balance of the account
40      * @param amount import to subtract to the balance
41      */
42     public synchronized void subtractAmount(double amount) {
43             double tmp=balance;
44             try {
45                 Thread.sleep(10);
46             } catch (InterruptedException e) {
47                 e.printStackTrace();
48             }
49             tmp-=amount;
50             balance=tmp;
51     }
52     
53 }
 

 

 
 
 
  5:实现一个ATM模拟类Bank,它使用subtractAmount()方法对账户的余额进行扣除,实现Runabl接口。
 
   具体代码:
 
    
 
 
 1 public class Bank implements Runnable {
 2 
 3     /**
 4      * The account affected by the operations
 5      */
 6     private Account account;
 7     
 8     /**
 9      * Constructor of the class. Initializes the account
10      * @param account The account affected by the operations
11      */
12     public Bank(Account account) {
13         this.account=account;
14     }
15     
16     
17     /**
18      * Core method of the Runnable
19      */
20     public void run() {
21         for (int i=0; i<100; i++){
22             account.subtractAmount(1000);
23         }
24     }
25 
26 }
 

 

 
  6:实现公司模拟类,调用addAmount()方法进行存钱,实现Runabl接口。
 
  具体代码:
 
  
 
 
 1 public class Company implements Runnable {
 2 
 3     /**
 4      * The account affected by the operations
 5      */
 6     private Account account;
 7     
 8     /**
 9      * Constructor of the class. Initializes the account
10      * @param account the account affected by the operations
11      */
12     public Company(Account account) {
13         this.account=account;
14     }
15     
16     /**
17      * Core method of the Runnable
18      */
19     public void run() {
20         for (int i=0; i<100; i++){
21             account.addAmount(1000);
22         }
23     }
 

 

 
  7:在主方法中调用测试:通过线程的join方法,在存期那,取钱线程模拟完毕后打印出结构。
 
  
 
 
 1 public class Main {
 2 
 3     /**
 4      * Main method of the example
 5      * @param args
 6      */
 7     public static void main(String[] args) {
 8         // Creates a new account ...
 9         Account    account=new Account();
10         // an initialize its balance to 1000
11         account.setBalance(1000);
12         
13         // Creates a new Company and a Thread to run its task
14         Company    company=new Company(account);
15         Thread companyThread=new Thread(company);
16         // Creates a new Bank and a Thread to run its task
17         Bank bank=new Bank(account);
18         Thread bankThread=new Thread(bank);
19         
20         // Prints the initial balance
21         System.out.printf("Account : Initial Balance: %f\n",account.getBalance());
22         
23         // Starts the Threads
24         companyThread.start();
25         bankThread.start();
26 
27         try {
28             // Wait for the finalization of the Threads
29             companyThread.join();
30             bankThread.join();
31             // Print the final balance
32             System.out.printf("Account : Final Balance: %f\n",account.getBalance());
33         } catch (InterruptedException e) {
34             e.printStackTrace();
35         }
36     }
37 }

 

 
 
  结果,相同时间内,存与取执行后应该是相等的。如果我们在方法中不去使用synchronized关键字,那么得出的结果就不对了。
相关TAG标签
上一篇:新型VBR木马来袭 电脑中招倒计时60秒关机重启
下一篇:威胁情报过多:你还要在虚假的安全感里待多久?
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站