synchronized 使用

 以前编程没有怎么接触过synchronized方法,不太了解,今天编程遇到了多个线程访问同一个共享资源的问题,google了下synchronized使用方法,网上有二种说法,第一种说法是当一个线程访问了某个对象中的synchronzied方法,其它线程可以继续访问其它的synchronized方法,第二个说法与第一种说法相反,不能访问。搞的我也不确定,更要命的是,这两种说法在网上一边又一边的转载,以讹传讹,要误导不少java新手。到底那一个是正确的,编个程序验证就清楚了

   下面是一个示例程序,有三个角色,一个家庭中的父亲,母亲,和儿子,同时在ATM取款机上向同一个银行账号进行取钱和查询的操作
1.银行类

  

Java代码   
  1. package com.sunnylocus.test;   
  2.   
  3. public class Bank  {   
  4.     private int money = 100;   
  5.     //取钱   
  6.     public synchronized void takeMoney(int num) {   
  7.             Thread.sleep(1000 * 5);   //取钱需要5秒   
  8.             money -= num;   
  9.     }   
  10.     //存钱   
  11.     public synchronized void addMoney(int num) {   
  12.             Thread.sleep(1000 * 10); //存钱需要10秒   
  13.             money += money;   
  14.     }   
  15.     //查询   
  16.     public int queryMoney() {   
  17.         return money;   
  18.     }   
  19. }  
package com.sunnylocus.test;    public class Bank  {   private int money = 100;   //取钱   public synchronized void takeMoney(int num) {     Thread.sleep(1000 * 5);   //取钱需要5秒     money -= num;   }   //存钱   public synchronized void addMoney(int num) {     Thread.sleep(1000 * 10); //存钱需要10秒     money += money;   }   //查询   public int queryMoney() {    return money;   }  }

 


2.父亲类

Java代码   
  1. package com.sunnylocus.test;   
  2.   
  3. import java.text.DateFormat;   
  4. import java.text.SimpleDateFormat;   
  5. import java.util.Date;   
  6.   
  7. public class Father extends Thread{   
  8.     private Bank bank;   
  9.     private int num;   
  10.        
  11.     DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象   
  12.        
  13.     public Father(Bank bank,int num) {   
  14.         this.bank = bank;   
  15.         this.num = num;   
  16.     }   
  17.   
  18.     public void run() {   
  19.         System.out.println("老爸正在取钱...      --"+dateFormate.format(new Date()));   
  20.         bank.takeMoney(num);   
  21.         System.out.println("老爸取走了"+num +"         --"+dateFormate.format(new Date()));   
  22.     }   
  23.        
  24. }  
package com.sunnylocus.test;    import java.text.DateFormat;  import java.text.SimpleDateFormat;  import java.util.Date;    public class Father extends Thread{   private Bank bank;   private int num;      DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象      public Father(Bank bank,int num) {    this.bank = bank;    this.num = num;   }     public void run() {    System.out.println("老爸正在取钱...      --"+dateFormate.format(new Date()));    bank.takeMoney(num);    System.out.println("老爸取走了"+num +"         --"+dateFormate.format(new Date()));   }     }  



3.母亲类

Java代码   
  1. package com.sunnylocus.test;   
  2.   
  3. import java.text.DateFormat;   
  4. import java.text.SimpleDateFormat;   
  5. import java.util.Date;   
  6.   
  7. public class Monther extends Thread{   
  8.     private Bank bank;   
  9.     private int num;   
  10.     DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象   
  11.        
  12.     public Monther(Bank bank,int num) {   
  13.         this.bank = bank;   
  14.         this.num = num;   
  15.     }   
  16.   
  17.     public void run() {   
  18.         System.out.println("老妈正在取钱....         "+dateFormate.format(new Date()));   
  19.         bank.takeMoney(num);   
  20.         System.out.println("老妈取走了"+num+"         --"+dateFormate.format(new Date()));   
  21.     }   
  22.        
  23. }  
package com.sunnylocus.test;    import java.text.DateFormat;  import java.text.SimpleDateFormat;  import java.util.Date;    public class Monther extends Thread{   private Bank bank;   private int num;   DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象      public Monther(Bank bank,int num) {    this.bank = bank;    this.num = num;   }     public void run() {    System.out.println("老妈正在取钱....         "+dateFormate.format(new Date()));    bank.takeMoney(num);    System.out.println("老妈取走了"+num+"         --"+dateFormate.format(new Date()));   }     }  



4.儿子类

Java代码   
  1. package com.sunnylocus.test;   
  2.   
  3. import java.text.DateFormat;   
  4. import java.text.SimpleDateFormat;   
  5. import java.util.Date;   
  6.   
  7. public class Sun extends Thread{   
  8.     private Bank bank;   
  9.     DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象   
  10.     public Sun(Bank bank) {   
  11.         this.bank = bank;   
  12.     }   
  13.   
  14.     public void run() {   
  15.         //查询余款   
  16.         System.out.println("儿子查询余额:"+bank.queryMoney() +"     --"+dateFormate.format(new Date()));   
  17.     }   
  18. }  
package com.sunnylocus.test;    import java.text.DateFormat;  import java.text.SimpleDateFormat;  import java.util.Date;    public class Sun extends Thread{   private Bank bank;   DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象   public Sun(Bank bank) {    this.bank = bank;   }     public void run() {    //查询余款    System.out.println("儿子查询余额:"+bank.queryMoney() +"     --"+dateFormate.format(new Date()));   }  }  



5.测试类

Java代码   
  1. package com.sunnylocus.test;   
  2.   
  3. public class Main {   
  4.     public static void main(String[] args) {   
  5.         //银行   
  6.         Bank bank = new Bank();   
  7.         //老爸   
  8.         Father father = new Father(bank,50);   
  9.         //老妈   
  10.         Monther monther = new Monther(bank,100);   
  11.         //儿子   
  12.         Sun sun = new Sun(bank);   
  13.            
  14.         new Thread(father).start();   
  15.         new Thread(monther).start();   
  16.         new Thread(sun).start();   
  17.            
  18.     }   
  19. }  
package com.sunnylocus.test;    public class Main {   public static void main(String[] args) {    //银行    Bank bank = new Bank();    //老爸    Father father = new Father(bank,50);    //老妈    Monther monther = new Monther(bank,100);    //儿子    Sun sun = new Sun(bank);        new Thread(father).start();    new Thread(monther).start();    new Thread(sun).start();       }  }  


输出结果:

Java代码   
  1. 老爸正在取钱...               --上午 11:52:01  
  2. 老妈正在取钱....              --上午 11:52:01  
  3. 儿子查询余额:100           --上午 11:52:01  
  4.   
  5. 老爸取走了50                 --上午 11:52:06  
  6. 老妈取了30                    --上午 11:52:11  
老爸正在取钱...               --上午 11:52:01  老妈正在取钱....              --上午 11:52:01  儿子查询余额:100           --上午 11:52:01    老爸取走了50                 --上午 11:52:06  老妈取了30                    --上午 11:52:11


   一共有三个线程,同时启动,父亲线程和母亲线程同时取款的操作,因为父亲线程已经占用了对象锁,所以母亲线程只能等到父亲执行完方法释放锁后,才能执行。即便父亲线程占用了对象锁,儿子线程也能调用非synchronzied方法
 

     我们把母亲类的取钱的方法改成存钱的操作,虽然不是同一个synchronized方法.也一样不能执行,必须等到父亲线程方法执行完毕后,才能进行存钱的操作

我的结论: 
     synchronized method(){}可以防止多个线程同时访问这个对象的synchronized方法,如果一个对象有多个synchronized方法,只要一个线 程访问了其中的一个synchronized方法,那么其它线程不能同时访问这个对象中的任何一个synchronized方法,但可以访问这个对象中的非synchronized方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值