线程同步案例

线程同步案例:

 1 package com.iotek.synchronizedtest;
 2 
 3 public class BankDemo {
 4 
 5     /** 线程同步案例
 6      * 对于线程同步,在java代码中需要完成2个操作:
 7      * (1)把竞争访问的资源标识为private
 8      * (2)同步哪些访问资源的代码,使用synchronized关键字来修饰方法或代码块
 9      * 当synchronized方法执行完成或发生异常时,会自动释放锁
10      * 案例:某银行卡账号上有500元现金,一个人拿着存折去柜台取钱,
11      * 同时另一个人拿着卡去ATM上取钱,各自取400元。现要求取钱的过程中不能
12      * 出现资源竞争:比如400元被取出2次,银行的账目不能小于0等
13      * 
14      * @param args
15      */
16     public static void main(String[] args) {
17         Bank bank = new Bank();
18         BankTherad p1 = new BankTherad(bank);
19         p1.start(); // 模拟柜台取钱
20         BankTherad p2 = new BankTherad(bank);
21         p2.start(); // 模拟ATM取钱,与模拟柜台取钱,是2个线程,竞争同一个资源:账户的余额
22 
23     }
24 
25 }
26 
27 class BankTherad extends Thread {
28     private Bank bank = null; // 声明一个银行对象的引用
29 
30     public BankTherad(Bank bank) {
31         this.bank = bank;
32     }
33 
34     public void run() {
35         System.out.println("取钱:" + bank.getMoney(400));
36     }
37 }
38 
39 class Bank {
40     private int money = 500; // 银行账户里的钱是一种竞争资源,设置为私有属性
41     private Object obj = new Object();
42     
43     /*
44      * synchronized关键字声明当前方法是同步方法,当一个线程去调用同步方法时,
45      * 这个线程就获取了当前对象的锁.获取当前对象锁的线程就去执行同步方法里的语句
46      * 其他的线程当调用同步方法时,只能等待,因为无法获取对象的锁,这个锁已被第一个 线程持有, 只有第一个线程释放对象的锁,方可进入
47      * 同步方法的作用就是确保方法里的代码同时只能有一个线程来访问,当同步方法运行完毕, 其他线程才能访问
48      */
49     /*
50      * public synchronized int getMoney(int number) { if (number < 0) { return
51      * -1; } else if (money < 0) { return -2; } else if (number - money > 0) {
52      * return -3; // 取钱数目大于银行卡账户余额 } else { // 除此之外,都是正常状态 try {
53      * Thread.sleep(1000); } catch (InterruptedException e) {
54      * e.printStackTrace(); } // 休眠1秒钟,模拟取钱的时间 money -= number; // 取钱后的账户余额
55      * System.out.println("余额:" + money); } return number; }
56      */
57     // 取钱的方法,返回取钱的数目
58     public int getMoney(int number) { 
59         //使用同步代码块: synchronized (this) { }  this代表获取的是当前对象的锁 
60         synchronized (obj) {  //此处获取任何对象的锁都是可以的
61             //this代表当前对象
62             if (number < 0) {//取钱数目不能小于0
63                 return -1;
64             } else if (money < 0) {//银行账户余额不能小于0
65                 return -2;
66             } else if (number - money > 0) {
67                 return -3; // 取钱数目大于银行卡账户余额
68             } else {
69                 // 除此之外,都是正常状态
70                 try {
71                     Thread.sleep(1000);
72                 } catch (InterruptedException e) {
73                     e.printStackTrace();
74                 } // 休眠1秒钟,模拟取钱的时间
75                 money -= number; // 取钱后的账户余额
76                 System.out.println("余额:" + money);
77             }
78         }
79         return number;
80     }
81 
82 }
原文地址:https://www.cnblogs.com/enjoyjava/p/8192666.html